home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 21 / AACD 21.iso / AACD / Programming / Comal / Comal.DOC < prev    next >
Text File  |  2001-04-11  |  412KB  |  15,051 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.   I. GETTING STARTED . . . . . . . . . . . . . . . . . . . . . . . . .    5
  9.     1 Hardware requierements . . . . . . . . . . . . . . . . . . . . .    5
  10.     2 Software requirements  . . . . . . . . . . . . . . . . . . . . .    5
  11.     3 Creating a backup disk . . . . . . . . . . . . . . . . . . . . .    5
  12.     4 Installing Comal on a floppy disk system . . . . . . . . . . . .    6
  13.     5 Installing Comal on a hard disk system . . . . . . . . . . . . .    6
  14.     6 Starting Comal from Workbench  . . . . . . . . . . . . . . . . .    6
  15.     7 Starting Comal from the Shell (the CLI)  . . . . . . . . . . . .    7
  16.     8 Setting the Comal environment  . . . . . . . . . . . . . . . . .    7
  17.       8.1 Setting the Comal TOOLTYPES  . . . . . . . . . . . . . . . .    7
  18.       8.2 The Preferences program Pref . . . . . . . . . . . . . . . .   11
  19.  
  20.   II. TUTORIAL . . . . . . . . . . . . . . . . . . . . . . . . . . . .   12
  21.     1 Your first Comal programs  . . . . . . . . . . . . . . . . . . .   12
  22.     2 Working with graphics  . . . . . . . . . . . . . . . . . . . . .   13
  23.     3 Repetition . . . . . . . . . . . . . . . . . . . . . . . . . . .   15
  24.     4 Selection  . . . . . . . . . . . . . . . . . . . . . . . . . . .   18
  25.     5 Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . .   20
  26.     6 Making modules . . . . . . . . . . . . . . . . . . . . . . . . .   23
  27.     7 Looking into modules . . . . . . . . . . . . . . . . . . . . . .   26
  28.     8 Making gadgets . . . . . . . . . . . . . . . . . . . . . . . . .   27
  29.     9 Event driven programs  . . . . . . . . . . . . . . . . . . . . .   31
  30.     10 Debugging programs  . . . . . . . . . . . . . . . . . . . . . .   33
  31.  
  32.   III. THE PROGRAMMING ENVIRONMENT . . . . . . . . . . . . . . . . . .   36
  33.     1 The keyboard . . . . . . . . . . . . . . . . . . . . . . . . . .   36
  34.     2 The mouse  . . . . . . . . . . . . . . . . . . . . . . . . . . .   37
  35.     3 The menus  . . . . . . . . . . . . . . . . . . . . . . . . . . .   38
  36.       3.1 The Project menu . . . . . . . . . . . . . . . . . . . . . .   38
  37.       3.2 The Edit menu  . . . . . . . . . . . . . . . . . . . . . . .   39
  38.       3.3 The Search menu  . . . . . . . . . . . . . . . . . . . . . .   40
  39.       3.4 The Macros menu  . . . . . . . . . . . . . . . . . . . . . .   40
  40.       3.5 The Settings menu  . . . . . . . . . . . . . . . . . . . . .   41
  41.       3.6 The Program menu . . . . . . . . . . . . . . . . . . . . . .   42
  42.       3.7 The Trace menu . . . . . . . . . . . . . . . . . . . . . . .   43
  43.  
  44.   IV. DESCRIPTION OF THE Comal LANGUAGE  . . . . . . . . . . . . . . .   45
  45.     1 Data types, variables and expressions  . . . . . . . . . . . . .   45
  46.       1.1 Identifiers  . . . . . . . . . . . . . . . . . . . . . . . .   45
  47.       1.2 Simple data types  . . . . . . . . . . . . . . . . . . . . .   45
  48.         1.2.1 Constants  . . . . . . . . . . . . . . . . . . . . . . .   46
  49.         1.2.2 Expressions  . . . . . . . . . . . . . . . . . . . . . .   47
  50.         1.2.3 Variables  . . . . . . . . . . . . . . . . . . . . . . .   51
  51.       1.3 Structured data types  . . . . . . . . . . . . . . . . . . .   53
  52.         1.3.1 Indexed variables  . . . . . . . . . . . . . . . . . . .   53
  53.         1.3.2 Strucs (records) . . . . . . . . . . . . . . . . . . . .   55
  54.       1.4 Dynamic variables. Pointer variables . . . . . . . . . . . .   56
  55.       1.5 Type definition  . . . . . . . . . . . . . . . . . . . . . .   61
  56.     2 Program flow control statements  . . . . . . . . . . . . . . . .   63
  57.  
  58.                                           1
  59.  
  60.  
  61.  
  62.  
  63.  
  64.       2.1 Selection  . . . . . . . . . . . . . . . . . . . . . . . . .   63
  65.         2.1.1 The IF statements  . . . . . . . . . . . . . . . . . . .   63
  66.         2.1.2 The CASE statement . . . . . . . . . . . . . . . . . . .   66
  67.       2.2 Repetition . . . . . . . . . . . . . . . . . . . . . . . . .   67
  68.       2.3 Branching  . . . . . . . . . . . . . . . . . . . . . . . . .   72
  69.         2.3.1 The GOTO statement . . . . . . . . . . . . . . . . . . .   72
  70.         2.3.1 The EXIT statement . . . . . . . . . . . . . . . . . . .   73
  71.     3 Procedures and functions . . . . . . . . . . . . . . . . . . . .   73
  72.       3.1 Procedures . . . . . . . . . . . . . . . . . . . . . . . . .   73
  73.         3.1.1 Procedures without parameters  . . . . . . . . . . . . .   74
  74.         3.1.2 Value parameters . . . . . . . . . . . . . . . . . . . .   75
  75.         3.1.3 Reference parameters . . . . . . . . . . . . . . . . . .   77
  76.         3.1.4 Local procedures . . . . . . . . . . . . . . . . . . . .   78
  77.         3.1.5 Local and global variables. CLOSED procedures  . . . . .   79
  78.       3.2 Functions  . . . . . . . . . . . . . . . . . . . . . . . . .   82
  79.     4 Exception handling . . . . . . . . . . . . . . . . . . . . . . .   83
  80.       4.1 The TRAP statement . . . . . . . . . . . . . . . . . . . . .   83
  81.       4.2 The TRAP ESC statement . . . . . . . . . . . . . . . . . . .   85
  82.     5 IO statements  . . . . . . . . . . . . . . . . . . . . . . . . .   86
  83.       5.1 The PRINT statement  . . . . . . . . . . . . . . . . . . . .   86
  84.       5.2 The INPUT statement  . . . . . . . . . . . . . . . . . . . .   88
  85.       5.3 Redirection of IO  . . . . . . . . . . . . . . . . . . . . .   89
  86.       5.4 System functions performing IO . . . . . . . . . . . . . . .   90
  87.       5.5 Other IO related statements and functions  . . . . . . . . .   90
  88.     6 File statements  . . . . . . . . . . . . . . . . . . . . . . . .   92
  89.       6.1 Sequential binary files  . . . . . . . . . . . . . . . . . .   93
  90.       6.2 Random access binary files . . . . . . . . . . . . . . . . .   95
  91.       6.3 ASCII files  . . . . . . . . . . . . . . . . . . . . . . . .   97
  92.       6.4 File system related functions  . . . . . . . . . . . . . . .   99
  93.       6.5 READ and DATA statements . . . . . . . . . . . . . . . . . .  100
  94.     7 Miscellaneous statements, procedures and functions . . . . . . .  103
  95.       7.1 DOS statements and functions . . . . . . . . . . . . . . . .  103
  96.       7.2 Time related statements and functions  . . . . . . . . . . .  106
  97.       7.3 Random numbers . . . . . . . . . . . . . . . . . . . . . . .  107
  98.       7.4 STOP and END statements  . . . . . . . . . . . . . . . . . .  108
  99.       7.5 Interrupt procedures . . . . . . . . . . . . . . . . . . . .  109
  100.       7.6 Mathematical functions . . . . . . . . . . . . . . . . . . .  109
  101.       7.7 Functions involving strings  . . . . . . . . . . . . . . . .  111
  102.       7.8 Other functions  . . . . . . . . . . . . . . . . . . . . . .  112
  103.     8 Objects  . . . . . . . . . . . . . . . . . . . . . . . . . . . .  113
  104.       8.1 Introduction to OOP  . . . . . . . . . . . . . . . . . . . .  113
  105.       8.2 Methods  . . . . . . . . . . . . . . . . . . . . . . . . . .  118
  106.       8.3 Inheritance  . . . . . . . . . . . . . . . . . . . . . . . .  120
  107.       8.4 Virtual methods  . . . . . . . . . . . . . . . . . . . . . .  122
  108.       8.5 Constructors . . . . . . . . . . . . . . . . . . . . . . . .  125
  109.       8.6 Destructors  . . . . . . . . . . . . . . . . . . . . . . . .  126
  110.     9 Modules  . . . . . . . . . . . . . . . . . . . . . . . . . . . .  128
  111.       9.1 Making modules . . . . . . . . . . . . . . . . . . . . . . .  128
  112.       9.2 Using modules  . . . . . . . . . . . . . . . . . . . . . . .  129
  113.       9.3 Signal procedures  . . . . . . . . . . . . . . . . . . . . .  130
  114.  
  115.                                           2
  116.  
  117.  
  118.  
  119.  
  120.  
  121.     10 Description of the standard modules . . . . . . . . . . . . . .  131
  122.       10.1 The System modules  . . . . . . . . . . . . . . . . . . . .  131
  123.         10.1.1 SystemCode  . . . . . . . . . . . . . . . . . . . . . .  131
  124.         10.1.2 System  . . . . . . . . . . . . . . . . . . . . . . . .  133
  125.       10.2 The graphics modules  . . . . . . . . . . . . . . . . . . .  135
  126.         10.2.1 Graphics  . . . . . . . . . . . . . . . . . . . . . . .  135
  127.         10.2.2 Turtle  . . . . . . . . . . . . . . . . . . . . . . . .  145
  128.       10.3 Catalog . . . . . . . . . . . . . . . . . . . . . . . . . .  149
  129.       10.4 Bob and sprite modules  . . . . . . . . . . . . . . . . . .  150
  130.       10.5 Memory  . . . . . . . . . . . . . . . . . . . . . . . . . .  152
  131.       10.6 CodeManInclude and InterpreterInclude . . . . . . . . . . .  153
  132.       10.7 StartProgram  . . . . . . . . . . . . . . . . . . . . . . .  153
  133.       10.9 Timer . . . . . . . . . . . . . . . . . . . . . . . . . . .  153
  134.       10.10 SerialComm . . . . . . . . . . . . . . . . . . . . . . . .  153
  135.       10.11 Operating system modules . . . . . . . . . . . . . . . . .  155
  136.         10.11.1 Library interface routines . . . . . . . . . . . . . .  155
  137.         10.11.2 Definitions for use in the library modules . . . . . .  156
  138.     11 The Comal Intuition Tools (CIT) . . . . . . . . . . . . . . . .  161
  139.       11.1 General description of CIT  . . . . . . . . . . . . . . . .  161
  140.       11.2 Simple CIT examples . . . . . . . . . . . . . . . . . . . .  164
  141.       11.3 CIT reference . . . . . . . . . . . . . . . . . . . . . . .  169
  142.         11.3.1 CITWorkbench  . . . . . . . . . . . . . . . . . . . . .  169
  143.         11.3.2 CITScreen . . . . . . . . . . . . . . . . . . . . . . .  169
  144.         11.3.3 CITWindow . . . . . . . . . . . . . . . . . . . . . . .  171
  145.         11.3.4 CITBorder . . . . . . . . . . . . . . . . . . . . . . .  175
  146.         11.3.5 CITView . . . . . . . . . . . . . . . . . . . . . . . .  176
  147.         11.3.6 CITGadgets  . . . . . . . . . . . . . . . . . . . . . .  176
  148.           11.3.6.1 TextGadget  . . . . . . . . . . . . . . . . . . . .  178
  149.           11.3.6.2 ButtonGadget  . . . . . . . . . . . . . . . . . . .  179
  150.           11.3.6.3 CheckboxGadget  . . . . . . . . . . . . . . . . . .  179
  151.           11.3.6.4 StringGadget  . . . . . . . . . . . . . . . . . . .  179
  152.           11.3.6.5 IntegerGadget . . . . . . . . . . . . . . . . . . .  180
  153.           11.3.6.6 SliderGadget  . . . . . . . . . . . . . . . . . . .  181
  154.           11.3.6.7 ScrollerGadget  . . . . . . . . . . . . . . . . . .  182
  155.           11.3.6.8 CycleGadget . . . . . . . . . . . . . . . . . . . .  183
  156.           11.3.6.9 RadioButtonGadget . . . . . . . . . . . . . . . . .  184
  157.           11.3.6.10 ListViewGadget . . . . . . . . . . . . . . . . . .  185
  158.           11.3.6.11 PaletteGadget  . . . . . . . . . . . . . . . . . .  187
  159.         11.3.7 CITText . . . . . . . . . . . . . . . . . . . . . . . .  188
  160.         11.3.8 CITGraphics . . . . . . . . . . . . . . . . . . . . . .  189
  161.         11.3.9 CITMenus  . . . . . . . . . . . . . . . . . . . . . . .  190
  162.         11.3.10 CITRequester . . . . . . . . . . . . . . . . . . . . .  194
  163.       11.4 Creating your own CIT classes . . . . . . . . . . . . . . .  194
  164.  
  165.   V. MAKING EXECUTABLE PROGRAMS  . . . . . . . . . . . . . . . . . . .  199
  166.     1 Comal code file  . . . . . . . . . . . . . . . . . . . . . . . .  199
  167.     2 Combined files . . . . . . . . . . . . . . . . . . . . . . . . .  199
  168.       2.1 Starting the Combiner from the editor  . . . . . . . . . . .  200
  169.       2.2 Starting the Combiner from Workbench . . . . . . . . . . . .  200
  170.       2.3 Starting the Combiner from the Shell (CLI) . . . . . . . . .  202
  171.  
  172.                                           3
  173.  
  174.  
  175.  
  176.  
  177.  
  178.     3 Using ToolTypes in executable files  . . . . . . . . . . . . . .  202
  179.  
  180.   VI. DESCRIPTION OF THE Comal SYSTEM  . . . . . . . . . . . . . . . .  204
  181.     1 The code manipulator Comal.CodeMan . . . . . . . . . . . . . . .  204
  182.     2 The interpreter Comal.Interpreter  . . . . . . . . . . . . . . .  211
  183.     3 The starter program Comal.Starter  . . . . . . . . . . . . . . .  217
  184.  
  185.   VII. THE Comal AREXX INTERFACE . . . . . . . . . . . . . . . . . . .  218
  186.     1 The editor AREXX interface . . . . . . . . . . . . . . . . . . .  218
  187.     2 The CodeMan AREXX interface  . . . . . . . . . . . . . . . . . .  225
  188.     3 The interpreter AREXX interface  . . . . . . . . . . . . . . . .  229
  189.     4 An AREXX script example  . . . . . . . . . . . . . . . . . . . .  230
  190.  
  191.   VIII. COMAL IO DEVICES . . . . . . . . . . . . . . . . . . . . . . .  232
  192.     1 What is a Comal device?  . . . . . . . . . . . . . . . . . . . .  232
  193.     2 Making new devices . . . . . . . . . . . . . . . . . . . . . . .  232
  194.     3 Making your own IO window  . . . . . . . . . . . . . . . . . . .  241
  195.  
  196.   IX. MASHINE CODED MODULES  . . . . . . . . . . . . . . . . . . . . .  243
  197.     1 The format of a mashine coded module . . . . . . . . . . . . . .  243
  198.       1.1 The interface part . . . . . . . . . . . . . . . . . . . . .  243
  199.       1.2 The initialization and signal routines . . . . . . . . . . .  244
  200.       1.3 The routine part . . . . . . . . . . . . . . . . . . . . . .  245
  201.     2 An assembler programmed module . . . . . . . . . . . . . . . . .  245
  202.     3 Programming modules in C . . . . . . . . . . . . . . . . . . . .  250
  203.       3.1 The interface part . . . . . . . . . . . . . . . . . . . . .  250
  204.       3.2 The procedures and functions . . . . . . . . . . . . . . . .  251
  205.       3.3 Linking the object files . . . . . . . . . . . . . . . . . .  252
  206.       3.4 An initialization routine  . . . . . . . . . . . . . . . . .  252
  207.       3.5 A signal routine . . . . . . . . . . . . . . . . . . . . . .  253
  208.       3.4 Using the script file MakeMod  . . . . . . . . . . . . . . .  253
  209.       3.5 The interface compiler CompInterface . . . . . . . . . . . .  254
  210.     4 Calling internal Comal routines from modules . . . . . . . . . .  254
  211.     5 Calling comal programmed routines from a module  . . . . . . . .  257
  212.     6 Making a library interface . . . . . . . . . . . . . . . . . . .  258
  213.  
  214.   X. APPENDIX  . . . . . . . . . . . . . . . . . . . . . . . . . . . .  261
  215.     A. Customizing the Comal text  . . . . . . . . . . . . . . . . . .  261
  216.     B. The format of the AREXX macro file  . . . . . . . . . . . . . .  262
  217.     C. Customizing Comal.lib . . . . . . . . . . . . . . . . . . . . .  263
  218.  
  219.  
  220.  
  221.  
  222.  
  223.  
  224.  
  225.  
  226.  
  227.  
  228.  
  229.                                           4
  230.  
  231.  
  232.  
  233.  
  234.  
  235.   I. GETTING STARTED
  236.  
  237.  
  238.   1 Hardware requierements.
  239.  
  240.   The Comal  programming system  will run  on any  Amiga computer having at
  241.   least 1 megabyte of main memory and one diskette drive.
  242.  
  243.   Although one disk drive will suffice an extra disk drive (or a hard disk) is
  244.   recommended.
  245.  
  246.  
  247.  
  248.   2 Software requirements.
  249.  
  250.   Comal requires Workbench 1.3 or higher to run.
  251.  
  252.   To be able to use the Comal Intuition Tool (CIT) Workbench 2.04 or higher
  253.   is needed.
  254.  
  255.  
  256.  
  257.   3 Creating a backup disk.
  258.  
  259.   Comal is supplied on two 3.5" floppy disks named Comal  and Comal.Extras.
  260.   Before installing Comal, make a backup copy of the original disks and store
  261.   these in a safe place.
  262.  
  263.   Before doing this make sure that the disks are write protected (you should
  264.   be able to look through the small hole in the plastic disk cover).
  265.  
  266.   If your Amiga has only one disk drive the backup is done in this way:
  267.  
  268.   1.  Put the write protected Comal (Comal.Extras) disk into a disk drive.
  269.  
  270.   2.  Select the Comal (Comal.Extras) disk by clicking once on its icon with
  271.       the left mouse button.
  272.  
  273.   3.  Choose the Copy item from the Icons menu (in WB1.3 the duplicate item
  274.       from the  Workbench menu)  and follow the instructions in the reques-
  275.       ters.
  276.  
  277.   4.  After the copy has been made, choose the  Rename item  from the Icons
  278.       menu (the  Workbench menu  in WB1.3)  and remove  the "copy_of_" from
  279.       the name.
  280.  
  281.   If your Amiga has two disk drives the backup is done in this way:
  282.  
  283.   1.  Put the write protected Comal (Comal.Extras) disk into one disk drive.
  284.  
  285.  
  286.                                           5
  287.  
  288.  
  289.  
  290.  
  291.  
  292.   2.  Write enable a blank floppy disk and put it into the other disk drive.
  293.  
  294.   3.  Select the Comal (Comal.Extras) disk by clicking once on its icon with
  295.       the left mouse button and drag it on top of the icon of the blank disk.
  296.  
  297.   4.  After the copy, remove the original Comal (Comal.Extras) disk from the
  298.       disk drive, select the "copy_of_Comal" ("copy_of_Comal.Extras") disk by
  299.       clicking on its icon with the left mouse button and choose the Rename
  300.       item from the Icons  menu (the  Workbench menu  in WB1.3)  and remove
  301.       the "copy_of_" from the name.
  302.  
  303.  
  304.  
  305.   4 Installing Comal on a floppy disk system.
  306.  
  307.   The disk  named Comal  is ready  to use. Put the copy of this disk into a
  308.   disk drive and open the disk by double clicking on its icon.
  309.  
  310.  
  311.  
  312.   5 Installing Comal on a hard disk system.
  313.  
  314.   Put the copy of your Comal.Extras disk into a disk drive and open the disk
  315.   by double clicking on its icon.
  316.  
  317.   Make an  empty drawer  on your  hard disk by using the New drawer item in
  318.   the Window menu (use the empty drawer in WB1.3) and  give the  drawer the
  319.   name Comal (or another name). Select InstallHD by clicking on its icon with
  320.   the left mouse button. Press the shift key and double click on the icon of
  321.   the newly created drawer.
  322.  
  323.   As an alternative to creating a new drawer your self you may just start the
  324.   InstallHD program by double clicking on its icon. Then you will be promp-
  325.   ted for  the name  of the destination drawer (that will be created if not
  326.   found).
  327.  
  328.   During the installation you will be asked to put in the other disk and you
  329.   will be asked if the ARexx demo scripts should be copied to the Rexx: di-
  330.   rectory (if ARexx is installed).
  331.  
  332.   The InstallHD program does not do anything else than copying needed files
  333.   to the selected drawer and (if you accepted) ARexx scripts to Rexx:.
  334.  
  335.  
  336.  
  337.   6 Starting Comal from Workbench.
  338.  
  339.   Comal may  be started  from Workbench  in the  normal Amiga way by double
  340.   clicking on the Comal icon.
  341.  
  342.  
  343.                                           6
  344.  
  345.  
  346.  
  347.  
  348.  
  349.   If you are using a one drive Amiga system you will be asked to change disk
  350.   once during the loading (Comal has to load some disk based libraries). Nor-
  351.   mally this is only the first time you are starting Comal. The next time the
  352.   libraries are already loaded.
  353.  
  354.   In stead of double clicking on the Comal icon you may click on the icon of
  355.   a Comal program text (an ASCII text containing a Comal program). By doing
  356.   this Comal will be started and the program will be loaded into the editor.
  357.  
  358.  
  359.  
  360.   7 Starting Comal from the Shell (the CLI).
  361.  
  362.   Comal may  be started  from the  Shell by executing a command of the for-
  363.   mat:
  364.  
  365.     Comal [startup parameters] [Program]
  366.  
  367.   where Program is the name of a Comal  program eventually  preceded by the
  368.   path to the directory containing the program and the optional startup para-
  369.   meters are of the same form as the tool types (se section 8.1).
  370.  
  371.   If you are specifying a program name, Comal will be started and  the pro-
  372.   gram will be loaded. The current directory will be the directory containing
  373.   the program.
  374.  
  375.   Example:
  376.  
  377.     Comal CITDemos/TinyPaint      (Start Comal and load CITDemos/TinyPaint)
  378.  
  379.     Comal WORKSPACE=100000        (Start Comal with 100000 Kb workspace)
  380.  
  381.  
  382.  
  383.   8 Setting the Comal environment.
  384.  
  385.   Several parameters used by the Comal  programming environment  may be set
  386.   either by  using the  standard Workbench  info requester  or by using the
  387.   Prefs program found in the Prefs drawer.
  388.  
  389.  
  390.   8.1 Setting the Comal TOOLTYPES.
  391.    
  392.   The info requester can be displayed by selecting the Comal  icon and then
  393.   select the  Information... item  from the Icons menu in Workbench (WB1.3:
  394.   select the Info item in the Workbench menu).
  395.  
  396.   The field Tool Types inside the Info requester is where  you can  set the
  397.   Comal parameters.  Each of the parameter are set by using one line of the
  398.   format:
  399.  
  400.                                           7
  401.  
  402.  
  403.  
  404.  
  405.  
  406.  
  407.     TOOLTYPE=ToolValue
  408.  
  409.  
  410.   The TOOLTYPE's and the ToolValue's you can use are described below. 
  411.  
  412.  
  413.     SCREEN
  414.  
  415.       By using the SCREEN tool type you select if Comal should open its own
  416.       screen or  use the workbench screen. The possible tool values are the
  417.       name of a public screen to be used (if the screen is not found it will
  418.       be created).
  419.  
  420.       Example:  SCREEN=Comal
  421.  
  422.       The only legal value for WB1.3 users is Workbench.
  423.  
  424.       The default value is a private screen.
  425.  
  426.  
  427.     DEPTH
  428.  
  429.       By using  the DEPTH  tool type  you select  depth of  the screen. The
  430.       default value is 2.
  431.  
  432.       Example:  DEPTH=4
  433.  
  434.  
  435.     LANGUAGE
  436.  
  437.       By using this tool type you may select the language of the texts used
  438.       in the Comal system.
  439.  
  440.       Example:  LANGUAGE=dansk
  441.  
  442.       The default language is English.
  443.  
  444.  
  445.     WINDOW
  446.  
  447.       By using this tool type you select the position and size of the editor
  448.       window at start. The format is
  449.  
  450.         WINDOW=LeftEdge,TopEdge,Width,Height
  451.  
  452.       Example:  WINDOW=95,30,540,200
  453.  
  454.  
  455.  
  456.  
  457.                                           8
  458.  
  459.  
  460.  
  461.  
  462.  
  463.     ENTERMODE
  464.  
  465.       Selects the effect of the enter key. The tool values are Down and In-
  466.       sert. If  you choose Insert the cursor is moved down and a new, empty
  467.       line is inserted each time the  ENTER key  is pressed.  If you choose
  468.       Down the  cursor is  moved down  but no new line is inserted. The de-
  469.       fault value is Insert.
  470.  
  471.       Example:  ENTERMODE=Down
  472.  
  473.       The behavior of the ENTER key  may  at  any  time  be  changed inside
  474.       Comal.
  475.  
  476.  
  477.     KEYWORD
  478.  
  479.       Selects the letters used to list keywords. The tool values are Capital
  480.       and Small. The default value is Capital.
  481.  
  482.       Example:  KEYWORD=Small
  483.  
  484.       This parameter may at any time be changed inside Comal.
  485.  
  486.  
  487.     BACKUP
  488.  
  489.       Selects the backup option. The tool values are  On and  Off. If  on a
  490.       backup file is created each time a program text is stored on disk. The
  491.       default value is On.
  492.  
  493.       Example:  BACKUP=Off
  494.  
  495.       This parameter may at any time be changed inside Comal.
  496.  
  497.  
  498.     ICON
  499.  
  500.       Selects the icon option. The tool values are On and Off. If on an icon
  501.       is created when a program is stored on disk. If the program is stored
  502.       as a text file, this icon can be used to start Comal and load the pro-
  503.       gram. If it is stored as a code file, the icon can be used to start exe-
  504.       cution of the program (without loading the editor). The default value is
  505.       On.
  506.  
  507.       Example:  ICON=Off
  508.  
  509.       This parameter may at any time be changed inside Comal.
  510.  
  511.  
  512.  
  513.  
  514.                                           9
  515.  
  516.  
  517.  
  518.  
  519.  
  520.     LINEEND
  521.  
  522.       Selects the lines are terminated in text files. The tool values are LF,
  523.       CR, CR+LF and PC. DThe default value is LF (standard Amiga).
  524.  
  525.       Example:  LINEEND=CR+LF
  526.  
  527.       This parameter may at any time be changed inside Comal.
  528.  
  529.  
  530.     AUTOVAR
  531.  
  532.       This tool type is used to select if a running program should create va-
  533.       riables automatically or if all variables has to be declared in a DIM or
  534.       LOCAL statement before use. The default value is On.
  535.  
  536.       Example:  AUTOVAR=Off
  537.  
  538.       This parameter may at any time be changed inside Comal.
  539.  
  540.  
  541.     EXECWINDOW
  542.  
  543.       This tool type is used to select if a running program should open the
  544.       standard  execute  window  (used  by  PRINT, INPUT etc.). The default
  545.       value is On.
  546.  
  547.       Example:  EXECWINDOW=Off
  548.  
  549.       This parameter may at any time be changed inside Comal.
  550.  
  551.  
  552.     PROGRAM
  553.  
  554.       Selects the size of the program  buffer. The  default value  is 25000
  555.       bytes.
  556.  
  557.       Example:  PROGRAM=20000
  558.  
  559.  
  560.  
  561.     WORKSPACE
  562.  
  563.       Selects the  size of the workspace used by a running program. The de-
  564.       fault value is 75000 bytes.
  565.  
  566.       Example:  WORKSPACE=60000
  567.  
  568.  
  569.  
  570.  
  571.                                          10
  572.  
  573.  
  574.  
  575.  
  576.  
  577.     STACK
  578.  
  579.       Selects the size of the stack for a running program. The default value
  580.       is 8Kb.
  581.  
  582.       Example:  STACK=16000
  583.  
  584.  
  585.     MACRO
  586.  
  587.       By using this tool type you select the name of the file that contains
  588.       the macro definitions that will be assigned to the function keys. The
  589.       default file is Comal.Macro.
  590.  
  591.       Example:  MACRO=Comal:MyMacro
  592.  
  593.  
  594.  
  595.   The tool  types (except  the SCREEN  and DEPTH tool types) can be used in
  596.   icons for program texts. If this is done, only the parameters for that pro-
  597.   ject is affected. If another project is started (see section 3.1) the standard
  598.   parameters or the values set in the Comal icon is used.
  599.  
  600.   The parameter values put into the  Comal icon  is read  even if  Comal is
  601.   started from the Shell.
  602.  
  603.  
  604.  
  605.   8.2 The Preferences program Pref.
  606.  
  607.   Most of  the parameters  that can  be set  by using  the TOOLTYPES in the
  608.   Comal info requester can be set in a  much more  comfortable way  by run-
  609.   ning the program Prefs in the Prefs drawer.
  610.  
  611.   NOTE: Workbench 1.3 users can only set the language in this way.
  612.  
  613.  
  614.  
  615.  
  616.  
  617.  
  618.  
  619.  
  620.  
  621.  
  622.  
  623.  
  624.  
  625.  
  626.  
  627.  
  628.                                          11
  629.  
  630.  
  631.  
  632.  
  633.  
  634.   II. TUTORIAL
  635.  
  636.   This chapter is intented to help beginners through the first difficult steps
  637.   in making their first programs. You will learn to make simple programs, to
  638.   use some of the menus in Comal and to debug your program.
  639.  
  640.   Skilled programmers may skip this chapter or just skim it.
  641.  
  642.  
  643.   1 Your first Comal programs.
  644.  
  645.   Having started  Comal by  clicking on its icon you will se a window - the
  646.   edit window. This window is used to type in your programs.
  647.  
  648.   Start by entering this program consisting of only one line:
  649.  
  650.     print "Hello there!"
  651.  
  652.   and press <ENTER>. Nothing happens except that the word print  is rewrit-
  653.   ten in capital.
  654.  
  655.   Now, let's  try to execute it. Press the mouse menu button and select the
  656.   Execute item in the Program menu  (or use  the alternative  short form of
  657.   this  menu  selection:  <right  Amiga>+<E>).  As a result a new window is
  658.   opened (the output window) and the text Hello  there! is  printed in this
  659.   window. After that the edit window is brought to front again.
  660.  
  661.   Let's remove  this program  and make  a little longer program. Select the
  662.   Clear Program Buffer menu item from the Project menu. As  a result  a re-
  663.   quester will  pop up.  This is  because the program you just made has not
  664.   been saved on disk. You will probably not want to save this little program,
  665.   so just click on Yes. The edit window will now be cleared and the execute
  666.   window will disappear.
  667.  
  668.   Enter this program:
  669.  
  670.     INPUT AT 10,5: "Type in your name: ": Name$
  671.  
  672.     PAGE  // Erase window
  673.  
  674.     PRINT AT 10,20: "Hello ",Name$,"!"
  675.     PRINT
  676.     PRINT AT 12,20: "Welcome to Comal."
  677.  
  678.  
  679.  
  680.   Remember to press <ENTER> after each line. Be careful to type in excactly
  681.   the same  as shown.  If you do not the Comal system will probably ask you
  682.   to correct the line.
  683.  
  684.  
  685.                                          12
  686.  
  687.  
  688.  
  689.  
  690.  
  691.   Let's execute this program. Select the Execute menu item from the Program
  692.   menu (or  use the short form: <right Amiga>+<E>). As a result the execute
  693.   window will again be opened and you are  asked to  type in  your name. Do
  694.   that and  terminate by pressing <ENTER>. The window will be cleared and a
  695.   text will be printed.
  696.  
  697.   If you did not typed excactly  as shown  the program  may stop,  an error
  698.   message will be printed in the status line of the edit window and the cur-
  699.   sor will be positioned on (or just after) the place where the error was de-
  700.   tected. Correct the error and execute the program again.
  701.  
  702.   If the program terminates without error you will notice that the edit win-
  703.   dow will be brought to front, so that you cannot see the text. This is bad.
  704.  
  705.   Use the cursor keys or the mouse to  move the  cursor to  the end  of the
  706.   program and add this line:
  707.  
  708.     WAIT 3  // Wait 3 secs
  709.  
  710.  
  711.   Run the  program again  (<right Amiga>+<E>).  The program waits 3 seconds
  712.   before it stops. Then you have the time to see the output.
  713.  
  714.  
  715.  
  716.   2 Working with graphics.
  717.  
  718.   In this and the following sections we will make programs that draws small
  719.   figures in  the window. But before we continue, you should clear the pro-
  720.   gram buffer. Use the the Clear  Program Buffer  menu item  in the Project
  721.   menu.
  722.  
  723.   Comal is an interactive programming language. This means that you can ex-
  724.   ecute commands immediately without putting them  into a  program. We will
  725.   use this facility to show you how some of the drawing routines works.
  726.  
  727.   Select the  Open Command  Window item  from the  Project menu (or use the
  728.   short form: <right Amiga>+<K>). As a result a little window  (the command
  729.   window) will appear in the top left corner of your screen. In this window
  730.   some of the Comal  statements may  be executed  as commands.  Try for in-
  731.   stance to write this line:
  732.  
  733.     PRINT 2+3
  734.  
  735.   and press  <ENTER>. The  expression will be calculated and the result (5)
  736.   will be printed at once.
  737.  
  738.   To be able to use the graphics routine you have to link one of the graphics
  739.   modules Graphics and Turtle into the system. We will choose Turtle.
  740.  
  741.  
  742.                                          13
  743.  
  744.  
  745.  
  746.  
  747.  
  748.   The linking is done by executing the line:
  749.  
  750.     USE Turtle
  751.  
  752.  
  753.   Type  this  line  into  the  command  window  and  terminate  by pressing
  754.   <ENTER>. Comal reads the module from  disk  and  makes  all  the routines
  755.   within this module accessible.
  756.  
  757.   Before you  can make drawings, you have to open the graphics system. This
  758.   is done by writing:
  759.  
  760.     graphicscreen(0)
  761.  
  762.   (remember to press <ENTER>).
  763.  
  764.   If you have typed in commands as above the execute window will  be opened
  765.   and a small triangle (a turtle) will be drawn in the middle of the window.
  766.  
  767.   Now we are ready to use the graphics routines in the Turtle module. Let's
  768.   move the turtle forward. This is done by writing the line
  769.  
  770.     forward(50)
  771.  
  772.   (remember <ENTER>). The result is that the turtle is moved  50 units for-
  773.   ward and a line is drawn behind it.
  774.  
  775.   The turtle may be turned in any direction. This is done by writing the line
  776.  
  777.     right(90)
  778.  
  779.   which turns the turtle 90o to the right.
  780.  
  781.   If you repeat these two commands three more times (each repetition is most
  782.   easily done by moving the cursor up two  lines and  then pressing <ENTER>
  783.   twice) a nice square will be drawn.
  784.  
  785.   In the Turtle module there are a lot of different graphics routines. Read
  786.   more about these in the description of the graphics modules.
  787.  
  788.   Before we leave this section you should close the graphics system by wri-
  789.   ting the line:
  790.  
  791.     textscreen
  792.  
  793.   and then  close the command window by clicking on its close gadget in the
  794.   upper left corner of the window.
  795.  
  796.  
  797.  
  798.  
  799.                                          14
  800.  
  801.  
  802.  
  803.  
  804.  
  805.   3 Repetition.
  806.  
  807.   The drawing routines used in the preceeding section  may be  used as pro-
  808.   gram statements as well. Here is a program that draws the square from that
  809.   section:
  810.  
  811.  
  812.     // Program 3.1
  813.  
  814.     USE Turtle
  815.  
  816.     graphicscreen(0)  // Open the graphics system
  817.  
  818.     forward(50)       // Draw a square
  819.     right(90)
  820.     forward(50)
  821.     right(90)
  822.     forward(50)
  823.     right(90)
  824.     forward(50)
  825.     right(90)
  826.  
  827.     WAIT 4            // Time to look at the drawing
  828.  
  829.     textscreen        // Close the graphics system
  830.  
  831.  
  832.   You may type in the program in the editor or load it from disk where it is
  833.   stored. Select the Open... menu item in the Project menu (or use the short
  834.   form: <right Amiga>+<O>). A file requester will open.
  835.  
  836.   Click on the scroll bar in the right side of the requester and move it to
  837.   the bottom.  Then click on the name Tutorial which will be written in the
  838.   drawer field of the requester (alternatively you may just write  the name
  839.   Tutorial in this field). Now select the file Prg3.1 and then press the OK
  840.   gadget. As a result the program will be loaded.
  841.  
  842.   Try to execute the  program (<right  Amiga>+<E>). It  should draw  a nice
  843.   square in  the execute  window. The program will wait four seconds before
  844.   the edit window will be brought to front.
  845.  
  846.   In the program, the two statements:
  847.  
  848.     forward(50)
  849.     right(90)
  850.  
  851.   are repeated four times. The program can be  made more  elegant by making
  852.   the Comal system automatically repeat the two statements. This can be done
  853.   by using the LOOP statement:
  854.  
  855.  
  856.                                          15
  857.  
  858.  
  859.  
  860.  
  861.  
  862.     LOOP 4 TIMES
  863.         :
  864.       statements to be repeated
  865.         :
  866.     ENDLOOP
  867.  
  868.  
  869.   Let's try to modify the program. Move the cursor to line number 9 (use the
  870.   cursor keys  or the  mouse). Select the Mark Block Start menu item in the
  871.   Edit menu (or short: <right Amiga>+<B>). The editor will change  to block
  872.   mode (which is written in the status line) and the cursor line (line 9) is
  873.   written in blue (red in WB 1.3). Move the cursor  down to  line number 14
  874.   using the  cursor key  (the mouse  cannot be used in block mode). As seen
  875.   the lines 9-14 are marked as a block.
  876.  
  877.   Now delete this block by selecting the Erase menu item. As a result a re-
  878.   quester will pop up and you are requested to confirm. Press the Yes gadget
  879.   to accept the operation.
  880.  
  881.   Move the cursor three lines up (to line 6) and press <ENTER> to insert an
  882.   extra line. Write the line
  883.  
  884.     LOOP 4 TIMES
  885.  
  886.   and don't  press <ENTER>. If you did press <ENTER> an extra line has been
  887.   inserted. Delete this by pressing <shift>+<Del>. Move the cursor down three
  888.   lines (line 10 just after right(90)). Note that the lines are indented while
  889.   you are moving down.
  890.  
  891.   Write the line
  892.  
  893.     ENDLOOP
  894.  
  895.   and press <ENTER> to insert an extra line.
  896.  
  897.   May be you should change the program header line (line 1). Move  the cur-
  898.   sor to  the end of this line and delete the last 1 by pressing back space
  899.   (the key on the left side of the Del key  above the  <ENTER> key). Change
  900.   the line to:
  901.  
  902.     // Program 3.2
  903.  
  904.  
  905.   The changed program should now look like:
  906.  
  907.  
  908.  
  909.  
  910.  
  911.  
  912.  
  913.                                          16
  914.  
  915.  
  916.  
  917.  
  918.  
  919.     // Program 3.2
  920.  
  921.     USE Turtle
  922.  
  923.     graphicscreen(0)  // Open the graphics system
  924.  
  925.     LOOP 4 TIMES
  926.       forward(50)     // Draw a square
  927.       right(90)
  928.     ENDLOOP
  929.  
  930.     WAIT 4            // Time to look at the drawing
  931.  
  932.     textscreen        // Close the graphics system
  933.  
  934.  
  935.   Try to execute the program to make sure that it works just as before.
  936.  
  937.   Save the  program on the RAM: disk (just as an exercise). Select the Save
  938.   As... menu item in the Project menu (short form: <right  Amiga>+<A>). The
  939.   file requester will open. Select Disks  and RAM: and write the name Prg3.2
  940.   in the File text field of the requester. Then save by clicking  on the OK
  941.   gadget (or by pressing <ENTER>).
  942.  
  943.   By using  the LOOP  statement it  is easy  to make the program draw other
  944.   figures. Change the LOOP section to
  945.  
  946.     LOOP 3 TIMES
  947.       forward(50)
  948.       right(120)
  949.     ENDLOOP
  950.  
  951.   to draw a triangle, or to
  952.  
  953.     LOOP 6 TIMES
  954.       forward(50)
  955.       right(60)
  956.     ENDLOOP
  957.  
  958.   to draw a hexagon. Or try this funny little figure by changing it to
  959.  
  960.     LOOP 20 TIMES
  961.       forward(50)
  962.       right(168)
  963.     ENDLOOP
  964.  
  965.  
  966.   Comal contains a number of  other  repetition  statements:  WHILE, REPEAT
  967.   and FOR statements. Se chapter IV for a complete description.
  968.  
  969.  
  970.                                          17
  971.  
  972.  
  973.  
  974.  
  975.  
  976.  
  977.   4 Selection.
  978.  
  979.   In section 3 we learned to draw triangles, squares etc. In this chapter we
  980.   will make a program that can draw any of these  figures dependent  of the
  981.   users choice.
  982.  
  983.   A skeleton for such a program would be:
  984.  
  985.     Program figures
  986.       initialize
  987.       print the possible choices
  988.       get users choice
  989.       draw the chosen figure
  990.  
  991.  
  992.   The initialization is simply:
  993.  
  994.     graphicscreen(0)
  995.  
  996.  
  997.   The printing section could be made in this way:
  998.  
  999.     PRINT AT 6,10: "Triangle ........ 3"
  1000.     PRINT AT 8,10: "Square .......... 4"
  1001.     PRINT AT 10,10: "Pentagon ........ 5"
  1002.     PRINT AT 12,10: "Hexagon ......... 6"
  1003.  
  1004.  
  1005.   The users choice is made by a single INPUT statement:
  1006.  
  1007.     INPUT AT 16,10: "Select figure: ": choice
  1008.  
  1009.  
  1010.   To draw  the correct figure we have to use of one of the selection state-
  1011.   ments in Comal. Here we will use the IF statement:
  1012.  
  1013.     IF choice=3 THEN
  1014.       draw triangle
  1015.     ELIF choice=4 THEN
  1016.       draw square
  1017.     ELIF choice=5 THEN
  1018.       draw pentagon
  1019.     ELIF choice=6 THEN
  1020.       draw hexagon
  1021.     ELSE
  1022.       print error
  1023.     ENDIF
  1024.  
  1025.  
  1026.  
  1027.                                          18
  1028.  
  1029.  
  1030.  
  1031.  
  1032.  
  1033.   The complete program looks like:
  1034.  
  1035.     // Program 4.1
  1036.  
  1037.     USE Turtle
  1038.  
  1039.     graphicscreen(0)
  1040.     ht
  1041.  
  1042.     PRINT AT 6,10: "Triangle ......... 3"
  1043.     PRINT AT 8,10: "Square ........... 4"
  1044.     PRINT AT 10,10: "Pentagon ......... 5"
  1045.     PRINT AT 12,10: "Hexagon .......... 6"
  1046.  
  1047.     INPUT AT 16,10: "Select figure: ": choice
  1048.  
  1049.     page
  1050.  
  1051.     IF choice=3 THEN    // Triangle
  1052.       LOOP 3 TIMES
  1053.         forward(50)
  1054.         right(120)
  1055.       ENDLOOP
  1056.     ELIF choice=4 THEN  // Square
  1057.       LOOP 4 TIMES
  1058.         forward(50)
  1059.         right(90)
  1060.       ENDLOOP
  1061.     ELIF choice=5 THEN  // Pentagon
  1062.       LOOP 5 TIMES
  1063.         forward(50)
  1064.         right(72)
  1065.       ENDLOOP
  1066.     ELIF choice=6 THEN  // Hexagon
  1067.       LOOP 6 TIMES
  1068.         forward(50)
  1069.         right(60)
  1070.       ENDLOOP
  1071.     ELSE
  1072.       PRINT AT 12,10: "I don't know that figure!"
  1073.     ENDIF
  1074.  
  1075.     WAIT 4
  1076.     textscreen
  1077.  
  1078.  
  1079.   You may read this program from the disk (<right Amiga>+<O>).  The name of
  1080.   the program is Prg4.1). Execute it. Remember that a selection of a number
  1081.   must be terminated by pressing <ENTER>.
  1082.  
  1083.  
  1084.                                          19
  1085.  
  1086.  
  1087.  
  1088.  
  1089.  
  1090.  
  1091.   5 Procedures.
  1092.  
  1093.   The program in section 4 would  be more  readable if  we could  write the
  1094.   selection part in this way:
  1095.  
  1096.     IF choice=3 THEN
  1097.       triangle
  1098.     ELIF choice=4 THEN
  1099.       square
  1100.     ELIF choice=5 THEN
  1101.       pentagon
  1102.     ELIF choice=6 THEN
  1103.       hexagon
  1104.     ELS
  1105.       PRINT AT 12,10: "I don't know that figure!"
  1106.     ENDIF
  1107.  
  1108.  
  1109.   To do  this we have to define procedures for each of the figures in ques-
  1110.   tion. The square procedure for instance would be:
  1111.  
  1112.     PROC square
  1113.       LOOP 4 TIMES
  1114.         forward(50)
  1115.         right(90)
  1116.       ENDLOOP
  1117.     ENDPROC square
  1118.  
  1119.  
  1120.   Let's try to change the program in this way.
  1121.  
  1122.   Load the program Prg4.1 into the editor (if it is not already  there) and
  1123.   move the  cursor to  line 17  (the first LOOP statement). Select the Mark
  1124.   Block Start menu item in the Edit menu (or short:  <right Amiga>+<B>) and
  1125.   move  the  cursor  three  lines  down  (so  that  the  whole LOOP-ENDLOOP
  1126.   structure is marked as a block).
  1127.  
  1128.   Cut the block off the program and move it into the clip board by selecting
  1129.   the Cut  menu item  in the Edit menu (short: <right Amiga>+<X>). Move one
  1130.   line up and press <ENTER> to make an empty line and write triangle in this
  1131.   line (this line works as a replacement for the removed block).
  1132.  
  1133.   Move to  the end  of the program by pressing <Ctrl>+<down arrow>, make an
  1134.   extra empty line by pressing <ENTER> and write
  1135.  
  1136.     PROC triangle
  1137.  
  1138.   and press <ENTER> to move to the next line.
  1139.  
  1140.  
  1141.                                          20
  1142.  
  1143.  
  1144.  
  1145.  
  1146.  
  1147.   Insert the block from the clip board by selecting the Paste menu  item in
  1148.   the  Edit  menu  (short:  <right  Amiga>+<V>)  and move to the line after
  1149.   ENDLOOP and write:
  1150.  
  1151.     ENDPROC triangle
  1152.  
  1153.   Make similar changes for the other figures. The result should look like:
  1154.  
  1155.     // Program 5.1
  1156.  
  1157.     USE Turtle
  1158.  
  1159.     graphicscreen(0)
  1160.     ht
  1161.  
  1162.     PRINT AT 6,10: "Triangle ......... 3"
  1163.     PRINT AT 8,10: "Square ........... 4"
  1164.     PRINT AT 10,10: "Pentagon ......... 5"
  1165.     PRINT AT 12,10: "Hexagon .......... 6"
  1166.     INPUT AT 16,10: "Select figure: ": choice
  1167.  
  1168.     PAGE
  1169.     IF choice=3 THEN    // Triangle
  1170.       triangle
  1171.     ELIF choice=4 THEN  // Square
  1172.       square
  1173.     ELIF choice=5 THEN  // Pentagon
  1174.       pentagon
  1175.     ELIF choice=6 THEN  // Hexagon
  1176.       hexagon
  1177.     ELSE
  1178.       PRINT AT 12,10: "I don't know that figure!"
  1179.     ENDIF
  1180.  
  1181.     WAIT 4
  1182.     textscreen
  1183.  
  1184.     // ********* end of main program **************
  1185.  
  1186.     PROC triangle
  1187.       LOOP 3 TIMES
  1188.         forward(50)
  1189.         right(120)
  1190.       ENDLOOP
  1191.     ENDPROC triangle
  1192.  
  1193.     PROC square
  1194.       LOOP 4 TIMES
  1195.         forward(50)
  1196.         right(90)
  1197.  
  1198.                                          21
  1199.  
  1200.  
  1201.  
  1202.  
  1203.  
  1204.       ENDLOOP
  1205.     ENDPROC square
  1206.  
  1207.     PROC pentagon
  1208.       LOOP 5 TIMES
  1209.         forward(50)
  1210.         right(72)
  1211.       ENDLOOP
  1212.     ENDPROC pentagon
  1213.  
  1214.     PROC hexagon
  1215.       LOOP 6 TIMES
  1216.         forward(50)
  1217.         right(60)
  1218.       ENDLOOP
  1219.     ENDPROC hexagon
  1220.  
  1221.  
  1222.   The program is not shorter neither is it faster, but it is much more read-
  1223.   able, since  you only need to read the first 30 lines to see what it does
  1224.   (provided you have used descriptive names).
  1225.  
  1226.   The four procedures at  the end  of the  program contain  almost the same
  1227.   code. We could use this fact to make the program shorter. A general Poly-
  1228.   gon procedure could be made in this way:
  1229.  
  1230.     PROC Polygon(n)
  1231.       LOOP n TIMES
  1232.         forward(50)
  1233.         right(360/n)
  1234.       ENDLOOP
  1235.     ENDPROC Polygon
  1236.  
  1237.  
  1238.   By using this, the four procedures should be changed to (note that the new
  1239.   procedure must  be written  Polygon and  not polygon or you will conflict
  1240.   with one of the procedures in the Turtle module):
  1241.  
  1242.     PROC triangle
  1243.       Polygon(3)
  1244.     ENDPROC triangle
  1245.  
  1246.     PROC square
  1247.       Polygon(4)
  1248.     ENDPROC square
  1249.  
  1250.     PROC pentagon
  1251.       Polygon(5)
  1252.     ENDPROC pentagon
  1253.  
  1254.  
  1255.                                          22
  1256.  
  1257.  
  1258.  
  1259.  
  1260.  
  1261.     PROC hexagon
  1262.       Polygon(6)
  1263.     ENDPROC hexagon
  1264.  
  1265.  
  1266.   Try to make these changes as an exercise. The changed version is stored on
  1267.   disk under the name Prg5.2. Execute the program to see if it still does the
  1268.   same.
  1269.  
  1270.   One of the advantages  of using  procedures is  that the  program is more
  1271.   readable. But it is also much easier to make changes in a program that uses
  1272.   procedures. Try for instance to type in the following little procedure at the
  1273.   end of your program:
  1274.  
  1275.     PROC Fwrd(length)
  1276.       IF length<10 THEN
  1277.         forward(length)
  1278.       ELSE
  1279.         Fwrd(length/3)
  1280.         left(60)
  1281.         Fwrd(length/3)
  1282.         right(120)
  1283.         Fwrd(length/3)
  1284.         left(60)
  1285.         Fwrd(length/3)
  1286.       ENDIF
  1287.     ENDPROC Fwrd
  1288.  
  1289.   and replace the line forward(50) in the polygon procedure (line 51 in the
  1290.   program Prg5.2) with the line
  1291.  
  1292.     Fwrd(50)
  1293.  
  1294.   Execute the program to see the effect of the changes. It is very surprising!
  1295.  
  1296.  
  1297.   6 Making modules.
  1298.  
  1299.   As you saw in the last section it is a good idea to hide "complicated" code
  1300.   in procedures  and put these procedures in a separate section of the pro-
  1301.   gram. Another good reason for using procedures is that the  same piece of
  1302.   code may  be reused.  The Polygon procedure is a good example of this (it
  1303.   was used four times).
  1304.  
  1305.   The idea of hiding and reusing code may be developped  further by putting
  1306.   the procedures into a module and store this module on disk. This is in fact
  1307.   what has been done in the Turtle module. In this section it will be shown
  1308.   how such  a module is made. As an example we will put the four procedures
  1309.   triangle, square, pentagon and hexagon into a module called Figures so that
  1310.   they can be used in other programs.
  1311.  
  1312.                                          23
  1313.  
  1314.  
  1315.  
  1316.  
  1317.  
  1318.  
  1319.   First you  have to  load the program Prg5.2 into the editor (<rightAmiga>
  1320.   +<O>). Then go to the line  before the  first procedure  (line 32). Press
  1321.   <ENTER> to insert an extra line and write the following in this empty line:
  1322.  
  1323.     MODULE Figures
  1324.  
  1325.  
  1326.   Go to  the end  of the program (note that the lines are being indented as
  1327.   you are moving down), insert an extra line and write:
  1328.  
  1329.     ENDMODULE Figures
  1330.  
  1331.  
  1332.   Now you have made an internal  module which  can be  tested before  it is
  1333.   stored on disk. But the module is not ready for test. You have to USE the
  1334.   Turtle module inside this module and you have to tell  which ones  of the
  1335.   procedures should be made accessible from outside. This is done in special
  1336.   EXPORT statements. The final module should look like this:
  1337.  
  1338.     MODULE Figures
  1339.  
  1340.       USE Turtle
  1341.  
  1342.       EXPORT triangle,square,pentagon,hexagon
  1343.  
  1344.       PROC triangle
  1345.         Polygon(3)
  1346.       ENDPROC triangle
  1347.  
  1348.       PROC square
  1349.         Polygon(4)
  1350.       ENDPROC square
  1351.  
  1352.       PROC pentagon
  1353.         Polygon(5)
  1354.       ENDPROC pentagon
  1355.  
  1356.       PROC hexagon
  1357.         Polygon(6)
  1358.       ENDPROC hexagon
  1359.  
  1360.       PROC Polygon(n)
  1361.         LOOP n TIMES
  1362.           forward(50)
  1363.           right(360/n)
  1364.         ENDLOOP
  1365.       ENDPROC Polygon
  1366.  
  1367.     ENDMODULE Figures
  1368.  
  1369.                                          24
  1370.  
  1371.  
  1372.  
  1373.  
  1374.  
  1375.  
  1376.  
  1377.   Put the USE statement and the  EXPORT statement  into the  module so that
  1378.   it looks as above.
  1379.  
  1380.   Now let's try to execute the program. Press <right Amiga>+<E> and select 3
  1381.   (triangle) and press <ENTER>.
  1382.  
  1383.   What happened? An error occured! The cursor is placed after the word tri-
  1384.   angle and  an error message in the status line tells you that the name is
  1385.   unknown. This is because you have not told the main program to import the
  1386.   procedures from the module. You have to add the line
  1387.  
  1388.     USE Figures
  1389.  
  1390.   in the start of the program (for instance just after the line: USE Turtle).
  1391.   The start of the main program should look like:
  1392.  
  1393.     // Program 6.1
  1394.  
  1395.     USE Turtle
  1396.     USE Figures
  1397.  
  1398.     graphicscreen(0)
  1399.  
  1400.  
  1401.   Having added the USE line to your program, you are ready to  test the mo-
  1402.   dule once more. This time it should be okay. The program is stored on disk
  1403.   under the name Prg6.1
  1404.  
  1405.   The next step in making a module is to store it on disk.
  1406.  
  1407.   First you have cut the module off the program and  move it  into the clip
  1408.   board. Go  to the  MODULE line  (line 34  of Prg6.1) and enter block mode
  1409.   (<right Amiga>+<B>). Move  to  the  ENDMODULE  line  (line  63).  Now the
  1410.   whole module is marked as a block. Cut it off the program (<right Amiga>+
  1411.   <X>).
  1412.  
  1413.   As the next step  you have  to open  a new  project. Select  the New menu
  1414.   item in  the Project  menu (<right  Amiga>+<N>). As a result a new editor
  1415.   window will be opened. It is named Project 2. In fact you  have started a
  1416.   new process  in the  Amiga. In  this new project you can edit and execute
  1417.   programs independent of what you are doing in  the original  project. And
  1418.   you can even run programs in the two projects in parallel. But we are not
  1419.   going to do that now.
  1420.  
  1421.   The clip board we have used is the standard Amiga clip board  so that you
  1422.   can get  the content  from the  newly started project (and other programs
  1423.   that uses this clip board). Select the Paste menu item  in the  Edit menu
  1424.   (<right Amiga>+<V>) and the module will be copied into your editor.
  1425.  
  1426.                                          25
  1427.  
  1428.  
  1429.  
  1430.  
  1431.  
  1432.  
  1433.   And now we have to store it on disk. But in contradiction to what we have
  1434.   done earlier, where we have stored programs on disk as  simple text files
  1435.   (ready to be loaded by any text editor like for instance MEmacs or ED), we
  1436.   have to store it in a special code form.
  1437.  
  1438.   Select the Save... menu item in the Program menu (no short form - sorry!).
  1439.   As a  result the well known file requester will open. Activate the Drawer
  1440.   text field by clicking on it with your mouse (the left mouse  button) and
  1441.   write
  1442.  
  1443.     Comal:Modules
  1444.  
  1445.  
  1446.   Then write the following name into the File text field:
  1447.  
  1448.     Figures.mod
  1449.  
  1450.   Be careful to write it correct! Press <ENTER> (or click on the OK gadget)
  1451.   to store the module.
  1452.  
  1453.   That's all. Close Project 2 by clicking on the close gadget and start your
  1454.   program in Project 1. You will notice that it starts reading the module from
  1455.   disk. But otherwise the program works as before.
  1456.  
  1457.   Store your program on disk in the drawer  Tutorial under  the name Prg6.2
  1458.   (<right Amiga>+<A>).
  1459.  
  1460.  
  1461.   7 Looking into modules.
  1462.  
  1463.   If you  are using externale modules stored on disk it may happen that you
  1464.   want to see the content of a specific module. If there is a written docu-
  1465.   mentation for  that module,  you may find the answer to your questions in
  1466.   this. But if you do not have such a documentation there is another possibi-
  1467.   lity.
  1468.  
  1469.   Load the program Prg6.2 (if it is not already in the editor) and execute it
  1470.   so that modules are loaded. Select the Show  Modules... menu  item in the
  1471.   Program menu (short: <right Amiga>+<H>). As a result a file requester like
  1472.   window will pop up showing you all modules loaded so far.
  1473.  
  1474.   You may wonder! Five modules are  shown  but  you  have  only  loaded the
  1475.   Turtle module and the Figures module. The explanation is easy. The Turtle
  1476.   module itself uses the Graphics module and the System module which itself
  1477.   uses the SystemCode module.
  1478.  
  1479.   Select the Figures module either by pressing <ENTER> or by clicking on the
  1480.   Accept gadget. As a result your Figures module is shown in the editor win-
  1481.   dow. The  status line  tells you that you are in module mode and what the
  1482.  
  1483.                                          26
  1484.  
  1485.  
  1486.  
  1487.  
  1488.  
  1489.   name of the module is. In  module mode  you can  move around  in the text
  1490.   but you cannot edit the text and a lot of functions are disabled.
  1491.  
  1492.   To go  back to  the main  program select  the Edit Main Program menu item
  1493.   in the Edit menu (short: <right Amiga>+<M>).
  1494.  
  1495.   Let's see the loaded modules again (<right Amiga>+<H>).
  1496.  
  1497.   Modules may be written  in Comal  or they  may be  mashine coded modules.
  1498.   The Figures,  Turtle and  System modules are Comal modules while Graphics
  1499.   and SystemCode are mashine coded modules. Select the Graphics module (for
  1500.   instance by double clicking on the name).
  1501.  
  1502.   This time  a new window is opened. The source of the module is not shown,
  1503.   but an interface containing all the  procedures and  functions are shown.
  1504.   Move around  in the  text by using the cursor keys or by using the scroll
  1505.   bars. Click on the close gadget in the top left  corner of  the window to
  1506.   remove the window.
  1507.  
  1508.   Try to look into the other modules, for instance the Turtle module. It is a
  1509.   large and rather complicated module that will convince you of  the advan-
  1510.   tage of hiding code in modules.
  1511.  
  1512.  
  1513.   8 Making gadgets.
  1514.  
  1515.   The programs  in sections  4-6 used  the INPUT  statement to  get a users
  1516.   choice. This is somewhat old fashioned. A better and more  Amiga like me-
  1517.   thod is  to use gadgets so that the user can press on the relevant gadget
  1518.   by using the mouse.
  1519.  
  1520.   By using the CIT-modules (CIT is short for Comal Intuition Tool) it is rela-
  1521.   tively easy  to make  programs with  gadgets. NOTE!  CIT can only be used
  1522.   with WB2.04 or higher.
  1523.  
  1524.   Load the program Prg6.1 or Prg6.2 (if not already in the editor). First add
  1525.   two USE  lines specifying the CIT-modules we are going to use: CITWindows
  1526.   and CITGadgets. The start of the program should look like this:
  1527.  
  1528.     // Program 6.1
  1529.  
  1530.     USE CITWindow
  1531.     USE CITGadgets
  1532.     USE Turtle
  1533.     USE Figures
  1534.  
  1535.     graphicscreen(0)
  1536.     ht
  1537.  
  1538.  
  1539.  
  1540.                                          27
  1541.  
  1542.  
  1543.  
  1544.  
  1545.  
  1546.   First we'll make a gadget for the triangle. This is done by executing a DIM
  1547.   statement of the form:
  1548.  
  1549.     DIM TriangleGad OF ButtonGadget
  1550.  
  1551.  
  1552.   The gadget  is a simple ButtonGadget. By using CIT a lot of other gadgets
  1553.   can be made, but in this section only button gadgets will be used.
  1554.  
  1555.   We have to tell CIT what the size of the gadget should  be and  where the
  1556.   gadget is to be placed. This is done in the following statements:
  1557.  
  1558.     TriangleGad.Size(120,20)    // Width = 120 and height = 20 pixels
  1559.     TriangleGad.Position(0,0)   // The upper left corner of the window
  1560.  
  1561.  
  1562.   The point  between TriangleGad  and Size/Position indicates that Size and
  1563.   Position are in fact methods in a data structure. Read chapter IV.8 if you
  1564.   want to  know more  about methods  and objects.  But here you do not need
  1565.   think more about that (just write as shown).
  1566.  
  1567.   Inside the gadget we want the label Triangle. This is specified in this way:
  1568.  
  1569.     TriangleGad.Label("Triangle",INSIDE)
  1570.  
  1571.  
  1572.   Now we have specified the layout and the position of the gadget. It is in-
  1573.   serted in the standard Comal window in this way:
  1574.  
  1575.     ComalWindow.InsObject(TriangleGad,Error)
  1576.  
  1577.  
  1578.   As a result of executing this statement the gadget will be visible in the
  1579.   window. If an error occurs an error message  is returned  in the variable
  1580.   Error. We will not test for errors until all gadgets are made.
  1581.  
  1582.   The gadgets for the other figures are made in the same way:
  1583.  
  1584.     DIM SquareGad OF ButtonGadget
  1585.     SquareGad.Size(120,20)
  1586.     SquareGad.Position(120,0)
  1587.     SquareGad.Label("Square",INSIDE)
  1588.     ComalWindow.InsObject(SquareGad,Error)
  1589.  
  1590.     DIM PentagonGad OF ButtonGadget
  1591.     PentagonGad.Size(120,20)
  1592.     PentagonGad.Position(240,0)
  1593.     PentagonGad.Label("Pentagon",INSIDE)
  1594.     ComalWindow.InsObject(PentagonGad,Error)
  1595.  
  1596.  
  1597.                                          28
  1598.  
  1599.  
  1600.  
  1601.  
  1602.  
  1603.     DIM HexagonGad OF ButtonGadget
  1604.     HexagonGad.Size(120,20)
  1605.     HexagonGad.Position(360,0)
  1606.     HexagonGad.Label("Hexagon",INSIDE)
  1607.     ComalWindow.InsObject(HexagonGad,Error)
  1608.  
  1609.  
  1610.   To be able to stop the program we have to add a Close gadget. This is also
  1611.   a button gadget and it is placed to the right of all the other gadgets:
  1612.  
  1613.     DIM Close OF ButtonGadget
  1614.     Close.Size(138,20)
  1615.     Close.Position(480,0)
  1616.     Close.Label("STOP",INSIDE)
  1617.     ComalWindow.InsObject(Close,Error)
  1618.  
  1619.  
  1620.   Now it's time to test for errors:
  1621.  
  1622.     IF Error THEN
  1623.       STOP "Could not create one or more gadgets"
  1624.     ENDIF
  1625.  
  1626.  
  1627.   To prevent  the graphics  routines from  overwriting the  gadgets we will
  1628.   change the graphics viewport:
  1629.  
  1630.     viewport(0,width-1,0,height-20)
  1631.  
  1632.  
  1633.   Having made  all the gadgets we are entering a loop where we can wait for
  1634.   some buttons to be pressed. The loop terminates when the  Close button is
  1635.   pressed:
  1636.  
  1637.  
  1638.     REPEAT
  1639.       WAIT
  1640.       clearscreen  
  1641.       IF TriangleGad.Pressed THEN
  1642.         triangle
  1643.       ELIF SquareGad.Pressed THEN
  1644.         square
  1645.       ELIF PentagonGad.Pressed THEN
  1646.         pentagon
  1647.       ELIF HexagonGad.Pressed THEN
  1648.         hexagon
  1649.       ENDIF
  1650.     UNTIL Close.Pressed
  1651.  
  1652.  
  1653.  
  1654.                                          29
  1655.  
  1656.  
  1657.  
  1658.  
  1659.  
  1660.   The last statement in the main program closes the graphics system:
  1661.  
  1662.     textscreen
  1663.  
  1664.  
  1665.   The complete program looks:
  1666.  
  1667.     // Program 8.1
  1668.  
  1669.     USE CITWindow
  1670.     USE CITGadgets
  1671.     USE Turtle
  1672.     USE Figures
  1673.  
  1674.     graphicscreen(0)
  1675.     ht
  1676.  
  1677.     DIM TriangleGad OF ButtonGadget
  1678.     TriangleGad.Size(120,20)
  1679.     TriangleGad.Position(0,0)
  1680.     TriangleGad.Label("Triangle",INSIDE)
  1681.     ComalWindow.InsObject(TriangleGad,Error)
  1682.  
  1683.     DIM SquareGad OF ButtonGadget
  1684.     SquareGad.Size(120,20)
  1685.     SquareGad.Position(120,0)
  1686.     SquareGad.Label("Square",INSIDE)
  1687.     ComalWindow.InsObject(SquareGad,Error)
  1688.  
  1689.     DIM PentagonGad OF ButtonGadget
  1690.     PentagonGad.Size(120,20)
  1691.     PentagonGad.Position(240,0)
  1692.     PentagonGad.Label("Pentagon",INSIDE)
  1693.     ComalWindow.InsObject(PentagonGad,Error)
  1694.  
  1695.     DIM HexagonGad OF ButtonGadget
  1696.     HexagonGad.Size(120,20)
  1697.     HexagonGad.Position(360,0)
  1698.     HexagonGad.Label("Hexagon",INSIDE)
  1699.     ComalWindow.InsObject(HexagonGad,Error)
  1700.  
  1701.     DIM Close OF ButtonGadget
  1702.     Close.Size(138,20)
  1703.     Close.Position(480,0)
  1704.     Close.Label("STOP",INSIDE)
  1705.     ComalWindow.InsObject(Close,Error)
  1706.  
  1707.     IF Error THEN
  1708.       STOP "Could not create one or more gadgets"
  1709.     ENDIF
  1710.  
  1711.                                          30
  1712.  
  1713.  
  1714.  
  1715.  
  1716.  
  1717.  
  1718.     viewport(0,width-1,0,height-20)
  1719.  
  1720.     REPEAT
  1721.       WAIT
  1722.       clearscreen  
  1723.       IF TriangleGad.Pressed THEN
  1724.         triangle
  1725.       ELIF SquareGad.Pressed THEN
  1726.         square
  1727.       ELIF PentagonGad.Pressed THEN
  1728.         pentagon
  1729.       ELIF HexagonGad.Pressed THEN
  1730.         hexagon
  1731.       ENDIF
  1732.     UNTIL Close.Pressed
  1733.  
  1734.     textscreen
  1735.  
  1736.  
  1737.   The program  is stored on disk under the name Prg8.1. Execute the program
  1738.   to see how it works. Before the program starts you will notice a lot of disk
  1739.   reading. The CIT system is in fact a rather complicated system and a lot of
  1740.   modules are used.
  1741.  
  1742.  
  1743.  
  1744.   9 Event driven programs.
  1745.  
  1746.   The program in section 8 can be made better. The final loop is in fact un-
  1747.   necessary. Why not let the buttons themselves call the procedures automa-
  1748.   tically?
  1749.  
  1750.   To do this we have to add event procedures to  each button.  Add the fol-
  1751.   lowing lines after the the insertion of the TriangleGad (after line 15 in
  1752.   PRG8.1):
  1753.  
  1754.     TriangleGad.EventHandler(TriangleEvent())
  1755.     PROC TriangleEvent(Id OF USHORT)
  1756.       clearscreen
  1757.       triangle
  1758.     ENDPROC TriangleEvent
  1759.  
  1760.  
  1761.   By doing this you are telling CIT that the procedure TriangleEvent should
  1762.   be called automatically when the triangle button is pressed.
  1763.  
  1764.   Add similar lines after the insertion af the other buttons except the close
  1765.   button.
  1766.  
  1767.  
  1768.                                          31
  1769.  
  1770.  
  1771.  
  1772.  
  1773.  
  1774.   By using event procedures that are automatically called by CIT the loop can
  1775.   now be changed to this single line:
  1776.  
  1777.     WHILE NOT Close.Pressed DO WAIT
  1778.  
  1779.  
  1780.   The complete program now looks:
  1781.  
  1782.     // Program 9.1
  1783.  
  1784.     USE CITWindow
  1785.     USE CITGadgets
  1786.     USE Turtle
  1787.     USE Figures
  1788.  
  1789.     graphicscreen(0)
  1790.     ht
  1791.  
  1792.     DIM TriangleGad OF ButtonGadget
  1793.     TriangleGad.Size(120,20)
  1794.     TriangleGad.Position(0,0)
  1795.     TriangleGad.Label("Triangle",INSIDE)
  1796.     ComalWindow.InsObject(TriangleGad,Error)
  1797.     TriangleGad.EventHandler(TriangleEvent())
  1798.     PROC TriangleEvent(Id OF USHORT)
  1799.       clearscreen
  1800.       triangle
  1801.     ENDPROC TriangleEvent
  1802.  
  1803.     DIM SquareGad OF ButtonGadget
  1804.     SquareGad.Size(120,20)
  1805.     SquareGad.Position(120,0)
  1806.     SquareGad.Label("Square",INSIDE)
  1807.     SquareGad.EventHandler(SquareEvent())
  1808.     ComalWindow.InsObject(SquareGad,Error)
  1809.     PROC SquareEvent(Id OF USHORT)
  1810.       clearscreen
  1811.       square
  1812.     ENDPROC SquareEvent
  1813.  
  1814.     DIM PentagonGad OF ButtonGadget
  1815.     PentagonGad.Size(120,20)
  1816.     PentagonGad.Position(240,0)
  1817.     PentagonGad.Label("Pentagon",INSIDE)
  1818.     PentagonGad.EventHandler(PentagonEvent())
  1819.     ComalWindow.InsObject(PentagonGad,Error)
  1820.     PROC PentagonEvent(Id OF USHORT)
  1821.       clearscreen
  1822.       pentagon
  1823.     ENDPROC PentagonEvent
  1824.  
  1825.                                          32
  1826.  
  1827.  
  1828.  
  1829.  
  1830.  
  1831.  
  1832.     DIM HexagonGad OF ButtonGadget
  1833.     HexagonGad.Size(120,20)
  1834.     HexagonGad.Position(360,0)
  1835.     HexagonGad.Label("Hexagon",INSIDE)
  1836.     HexagonGad.EventHandler(HexagonEvent())
  1837.     ComalWindow.InsObject(HexagonGad,Error)
  1838.     PROC HexagonEvent(Id OF USHORT)
  1839.       clearscreen
  1840.       hexagon
  1841.     ENDPROC HexagonEvent
  1842.  
  1843.     DIM Close OF ButtonGadget
  1844.     Close.Size(138,20)
  1845.     Close.Position(480,0)
  1846.     Close.Label("STOP",INSIDE)
  1847.     ComalWindow.InsObject(Close,Error)
  1848.  
  1849.     IF Error THEN
  1850.       STOP "Could not create one or more gadgets"
  1851.     ENDIF
  1852.  
  1853.     viewport(0,width-1,0,height-21)
  1854.  
  1855.     WHILE NOT Close.Pressed DO WAIT
  1856.  
  1857.     textscreen
  1858.  
  1859.  
  1860.   Some programmers may find this program rather strange. It looks as if the
  1861.   program does not do anything but waiting for the close gadget to be pres-
  1862.   sed (in the WHILE statement).
  1863.  
  1864.   But it does! While you are waiting for the close button to be pressed all
  1865.   your event procedures are called automatically.
  1866.  
  1867.   This sort of a program is called an event driven program.
  1868.  
  1869.   The changed version is stored on disk under the name  Prg9.1. Execute the
  1870.   program to see if it still does the same.
  1871.  
  1872.  
  1873.  
  1874.   10 Debugging programs.
  1875.  
  1876.   The Comal system has an integrated debugger that allow you to examine the
  1877.   behavior of your programs. To show how it works enter this little program
  1878.   (that calculates the number 6!=720):
  1879.  
  1880.  
  1881.  
  1882.                                          33
  1883.  
  1884.  
  1885.  
  1886.  
  1887.  
  1888.     // Program 10.1
  1889.  
  1890.     n:=6
  1891.  
  1892.     fak:=1
  1893.     WHILE n>0 DO
  1894.       fak:=fak*n
  1895.       n:=n-1
  1896.     ENDWHILE
  1897.  
  1898.     PRINT fak
  1899.  
  1900.   or load it from disk (Prg10.1 in the Tutorial drawer).
  1901.  
  1902.   Select the  Trace Mode? menu item in the Program menu (no short form). As
  1903.   a result a little window (the watch window) is opned and the first execut-
  1904.   able line (here n:=6) is printed in the reverse pen color. The status line
  1905.   shows that you are now in trace mode. In trace  mode you  can move around
  1906.   in the text but you cannot edit the text and a lot of functions are disab-
  1907.   led.
  1908.  
  1909.   Select the Execute One Step menu item from the Trace  menu (short: <right
  1910.   Amiga>+<T>). As a result the current line will be executed and the next line
  1911.   (fak:=1) is printed in the reverse pen color. Continue to execute steps 4-5
  1912.   times by pressing <right Amiga>+<T>.
  1913.  
  1914.   As you see, you are able to follow the execution step by step. But to exa-
  1915.   mine the execution in detail it is necessary to watch the value of certain
  1916.   expressions. Select  the New  Watch Expression  menu item  from the Trace
  1917.   menu (no short form). A requester will pop up. Write n into the text field
  1918.   of the  requester and  press <ENTER>  to accept. Now the current value of
  1919.   the variable n is  shown  in  the  watch  window.  Select  the  New Watch
  1920.   Expression menu  item once more and enter the name fak. Also the value of
  1921.   this variable will be shown in the watch window as  soon as  you have ac-
  1922.   cepted it.
  1923.  
  1924.   Continue to  execute program  steps (<right  Amiga>+<T>) and  look at the
  1925.   watch window. The current value of the watch variables are  updated after
  1926.   each step.
  1927.  
  1928.   If you  have not stepped to the end of the program (the watch window will
  1929.   close) try to remove a watch expression by double clicking  on it  in the
  1930.   watch window. You will be asked to confirm.
  1931.  
  1932.   Step to the end of the program and start tracing again. The actual line is
  1933.   again n:=0. The watch window tells you that  the variable  is not defined
  1934.   (you has not yet executed the line). Set a break point at line 8 (the line
  1935.   n:=n-1) by double clicking on the line. The line will be marked as a break
  1936.   point line.
  1937.  
  1938.  
  1939.                                          34
  1940.  
  1941.  
  1942.  
  1943.  
  1944.  
  1945.   Start execution  by selecting  the Continue  Execution menu item from the
  1946.   Program menu (short: <right Amiga>+<G>). The execution starts and it stops
  1947.   the first time the break point line is met. Note the value of the watch ex-
  1948.   pression.
  1949.  
  1950.   Remove the break point by double clicking on it once more and execute the
  1951.   program to the end.
  1952.  
  1953.   Let's look at another example. Load the program Prg10.2 from the Tutorial
  1954.   drawer (<right Amiga>+<O>). This program  counts  the  occurences  of one
  1955.   (small) text in another (bigger) text.
  1956.  
  1957.   Enter the  trace mode  (Program menu) and add the following watches: pos,
  1958.   pattern$, text$ and Cnt.  Note that  no one  is defined  yet. Single step
  1959.   (<right Amiga>+<T>) 12 times.
  1960.  
  1961.   Note that each time the line :
  1962.  
  1963.     Cnt:=1+Count(pattern$,text$(pos+1..))
  1964.  
  1965.   is executed, the next line to be executed is the first line of the function
  1966.   Count, that is called in this line. This can be avoided by selecting the Exe-
  1967.   cute One Line menu item from the Trace menu (short: <right Amiga>+<L>).
  1968.  
  1969.   By using  the Execute  One Line command the whole function and all recur-
  1970.   sive calls to this function will be executed until execution returns to the
  1971.   same level as before. Try it to see how it works.
  1972.  
  1973.  
  1974.  
  1975.  
  1976.  
  1977.  
  1978.  
  1979.  
  1980.  
  1981.  
  1982.  
  1983.  
  1984.  
  1985.  
  1986.  
  1987.  
  1988.  
  1989.  
  1990.  
  1991.  
  1992.  
  1993.  
  1994.  
  1995.  
  1996.                                          35
  1997.  
  1998.  
  1999.  
  2000.  
  2001.  
  2002.   III. THE PROGRAMMING ENVIRONMENT
  2003.  
  2004.   After start  Comal will  open its  own screen and a window in this screen
  2005.   (the editor window) and you may start typing  in your  program or  load a
  2006.   program from disk.
  2007.  
  2008.   From within  the editor  you may  edit programs, load programs from disk,
  2009.   start executing programs and much more.
  2010.  
  2011.  
  2012.   1 The keyboard.
  2013.  
  2014.   The editor works much like any other editor  except that  it makes syntax
  2015.   control of all the lines entered and organize the program lines with correct
  2016.   indention etc.
  2017.  
  2018.   All changes will be put into the program buffer immediately. What you see
  2019.   om the  screen is the same as is in the buffer. The only exception is the
  2020.   cursor line. It will not be put into the program buffer before you try to
  2021.   leave the line (by using the cursor keys, the ENTER key or the mouse). By
  2022.   pressing <Esc> the line will be restored to the content of the buffer.
  2023.  
  2024.   Certain keys have special functions. Here is a description of these keys and
  2025.   their functions:
  2026.  
  2027.  
  2028.     <shift>+<cur up>            move to top of window or show
  2029.                                 previous page
  2030.  
  2031.     <Ctrl>+<cur up>             move to start of text
  2032.  
  2033.  
  2034.     <shift>+<cur down>          move to bottom of window or show
  2035.                                 next page
  2036.  
  2037.     <Ctrl>+<cur down>           move to end of text
  2038.  
  2039.  
  2040.     <Alt>+<cur left>            scroll line right
  2041.  
  2042.  
  2043.     <Alt>+<cur right>           scroll line left
  2044.  
  2045.  
  2046.     <Alt>+<cur up>              scroll text down
  2047.  
  2048.  
  2049.     <Alt>+<cur down>            scroll text up
  2050.  
  2051.  
  2052.  
  2053.                                          36
  2054.  
  2055.  
  2056.  
  2057.  
  2058.  
  2059.     < <- >                      delete character before cursor
  2060.  
  2061.  
  2062.     <Del>                       delete character under cursor
  2063.  
  2064.  
  2065.     <shift>+<Del>               delete cursor line
  2066.  
  2067.  
  2068.     <shift>+<Ins>               toggles  insert/replace  mode - the current
  2069.                                 state is shown in the status line
  2070.  
  2071.  
  2072.     <shift>+<Alt>+<Ins>         insert line
  2073.  
  2074.  
  2075.     <Esc>                       restore line
  2076.  
  2077.  
  2078.  
  2079.   On Amiga's without the  numeric keys  (Amiga 600)  the following replace-
  2080.   ments for the <Ins> key can be used:
  2081.  
  2082.     <shift>+<Ins>         ->    <shift>+<Alt>+<cur right>
  2083.  
  2084.                                     or
  2085.  
  2086.                                 <<Alt>+<RETURN>
  2087.  
  2088.  
  2089.     <shift>+<Alt>+<Ins>   ->    <shift>+<Alt>+<cur down>
  2090.  
  2091.                                     or
  2092.  
  2093.                                 <shift>+<Alt>+<RETURN>
  2094.  
  2095.  
  2096.  
  2097.   2 The mouse.
  2098.  
  2099.   The mouse  can be  used to move the cursor around in the the text. If you
  2100.   move to another line the previous cursor line will be syntax checked and if
  2101.   the syntax is not correct an error message will pop up and cursor will not
  2102.   be moved.
  2103.  
  2104.   On the right side of the editor window you will find a scroll bar. The po-
  2105.   sition of the scroller inside the container shows the approximate position of
  2106.   the window inside the whole text and the size of  the scroller  shows the
  2107.   size of the window compared to the whole text.
  2108.  
  2109.  
  2110.                                          37
  2111.  
  2112.  
  2113.  
  2114.  
  2115.  
  2116.   By moving  the scroller  the window is moved inside the text. Like before
  2117.   this will result in a syntax controll of the previos cursor line and if the
  2118.   syntax is  not correct an error message will pop up and the scroller (the
  2119.   window) will not be moved.
  2120.  
  2121.  
  2122.   3 The menus.
  2123.  
  2124.   Most of the commands  that can  be executed  from the  editor are reached
  2125.   through the menus.
  2126.  
  2127.  
  2128.   3.1 The Project menu.
  2129.  
  2130.   The Project menu is placed far to the left. It contains the following items:
  2131.  
  2132.     New
  2133.       By selecting this a new project with its own editor window and its own
  2134.       program buffer will be opened.
  2135.  
  2136.     Open
  2137.       A file requester will pop up and you may select the name of a program
  2138.       to load. The program file must be a text file.
  2139.  
  2140.       After the load the name of the file will be shown in the screen title
  2141.       line.
  2142.  
  2143.     Save
  2144.       Store program buffer on disk as a text file. If there is a current name
  2145.       this will be used. Otherwise a requester will pop up.
  2146.  
  2147.     Save As
  2148.       Store program buffer on disk as a text file. A requester will pop up so
  2149.       that you can select a name.
  2150.  
  2151.     File
  2152.       An extended form of the file requester will pop up.  From this  it is
  2153.       possible to rename files, delete files, copy files, move files from one
  2154.       directory to another, make a new directory and a new drawer (a direc-
  2155.       tory with a drawer info file).
  2156.  
  2157.       Delete, copy  and move  accepts the  selection of more than one file.
  2158.       Press the shift key while selecting the next file(s).
  2159.  
  2160.     New Shell
  2161.       A new Shell (CLI) will open.
  2162.  
  2163.     Print
  2164.       Output the program in the program buffer to a printer.
  2165.  
  2166.  
  2167.                                          38
  2168.  
  2169.  
  2170.  
  2171.  
  2172.  
  2173.     Open Command Window
  2174.       This will open a  command  window  where  you  may  type  in commands
  2175.       like you are used to in other Comal's.
  2176.  
  2177.       There are  no special  commands like  LIST, ENTER  etc. The only com-
  2178.       mands you can use is PRINT, DIR, CHDIR etc.
  2179.  
  2180.     About
  2181.       Useful information about the system will be shown
  2182.  
  2183.     Clear Program Buffer
  2184.       The program in the program buffer will be erased. You  will be warned
  2185.       if the program in the buffer has not been saved since last change.
  2186.  
  2187.     Quit Project
  2188.       The current project will be terminated and if it the only project the
  2189.       Comal system will terminate.
  2190.  
  2191.       You will be warned if the program in  the buffer  has not  been saved
  2192.       since last change.
  2193.  
  2194.  
  2195.   3.2 The Edit menu.
  2196.  
  2197.   The menu  to theright  of the  Project menu  is the  Edit menu. This menu
  2198.   contains the following items:
  2199.  
  2200.     Mark Block Start
  2201.       The cursor line will be one end of a block and it will be printed in the
  2202.       inverse pen  color. Select  the other  end of the block by moving the
  2203.       cursor (cursor up/down, PgUp/Dn) or by moving the scroll bar.
  2204.  
  2205.       The status line will change  from  Insert/Replace  to  Block  and you
  2206.       cannot edit the program.
  2207.  
  2208.       If you are already in block mode this mode will be terminated.
  2209.  
  2210.     Cut
  2211.       The marked  block will  be cut  off the  text and moved into the clip
  2212.       board.
  2213.  
  2214.     Copy
  2215.       A copy of the marked block block will be moved into the clip board
  2216.  
  2217.     Paste
  2218.       The content of the clip board will be inserted in the program.
  2219.  
  2220.     Erase
  2221.       The marked block will be erased. You will be prompted to confirm.
  2222.  
  2223.  
  2224.                                          39
  2225.  
  2226.  
  2227.  
  2228.  
  2229.  
  2230.     Insert file
  2231.       A program text file will be inserted at the cursor line.
  2232.  
  2233.     Save Block
  2234.       Store the marked block on disk as a text file.
  2235.  
  2236.     Print block
  2237.       Print out the marked block.
  2238.  
  2239.     Edit Main Program
  2240.       If the editor contains a module you may turn back to the main program
  2241.       by using this menu.
  2242.  
  2243.  
  2244.  
  2245.   Comal uses  the clipboard.device of the Amiga so that blocks may be moved
  2246.   between different projects (started by the New item in the  Project menu)
  2247.   or other text editors using this device.
  2248.  
  2249.  
  2250.   3.3 The Search menu.
  2251.  
  2252.   The third menu contains only these three items:
  2253.  
  2254.     Search
  2255.       A requester will pop up and you may enter a searh string.
  2256.  
  2257.     Search & Replace
  2258.       As before but also a replace string has to be entered.
  2259.  
  2260.       When a match is found you will be asked if the string should be repla-
  2261.       ced. After the answer the search will continue. Use Esc to abort.
  2262.  
  2263.     Search Again
  2264.       The previous search/search & replace will be resumed.
  2265.  
  2266.  
  2267.   Note that the search is case sensitive.
  2268.  
  2269.  
  2270.  
  2271.   3.4 The Macros menu.
  2272.  
  2273.   A macro is an ARexx script that can be used  to add  new commands  to the
  2274.   editor. The ARexx interface will be described in detail later. Here you will
  2275.   find only a short description of the menu items:
  2276.  
  2277.     Assign Macro
  2278.       This item contains a subitem for each function key (F1..F10).
  2279.  
  2280.  
  2281.                                          40
  2282.  
  2283.  
  2284.  
  2285.  
  2286.  
  2287.       By selecting one of these a requester will pop up an you  may enter a
  2288.       macro string to be assigned to that function key. The macro string may
  2289.       be the name of  an ARexx  script file  (which must  be placed  in the
  2290.       REXX: directory) or an ARexx command.
  2291.  
  2292.     Load
  2293.       Load a complete set of assignments for the function key.
  2294.  
  2295.     Save
  2296.       Save the current set of assignment for the function keys on disk.
  2297.  
  2298.  
  2299.   At the  start of  a project  a macro file is read and assignments for the
  2300.   function keys are made according to the definitions in this file. The name
  2301.   of this file is Comal.macro unless another name is specified by the MACRO
  2302.   tool type (se section I.9).
  2303.  
  2304.   If ARexx is not installed in the system this menu is disabled (goasted).
  2305.  
  2306.  
  2307.  
  2308.   3.5 The Settings menu.
  2309.  
  2310.   In the Settings menu various parameters may be changed. The content is:
  2311.  
  2312.     New Line At <ENTER>
  2313.       If selected a new line will be inserted after the current line when the
  2314.       enter key is pressed.
  2315.  
  2316.     Keywords In Capital
  2317.       Some people prefer small letters. They are more readable they say. With
  2318.       this item you may  choose to  print keywords  in upper  or lower case
  2319.       letters.
  2320.  
  2321.     Create Backup
  2322.       If selected a backup file will be created when a program is saved.
  2323.  
  2324.     Create Icon
  2325.       If  selected  an  icon  will  be  created when a program is saved. By
  2326.       clicking on this icon Comal will be started  and the  program will be
  2327.       loaded.
  2328.  
  2329.       All the  options selected in this menu wil be stored in the tool type
  2330.       array of the icon.
  2331.  
  2332.     Store Window Parameters
  2333.       The window position and size will be stored along with  other parame-
  2334.       ters in the icon (if icon is selected). This is useful if more than one
  2335.       project is loaded at a time.
  2336.  
  2337.  
  2338.                                          41
  2339.  
  2340.  
  2341.  
  2342.  
  2343.  
  2344.     ASCII File Format
  2345.       This item has four subitems:
  2346.  
  2347.         LF      -   line end is LF  (standard Amiga)
  2348.  
  2349.         CR      -   line end is CR
  2350.  
  2351.         CR+LF   -   line end is CR+LF
  2352.  
  2353.         PC      -   program is stored in PC format (line end  is CR+LF) and
  2354.                     characters are converted.
  2355.  
  2356.  
  2357.     Automatic variables?
  2358.       Selects if variables in a program should be created automatically or if
  2359.       they must be declared in a DIM or LOCAL statement before use.
  2360.  
  2361.  
  2362.     Execute IO Window?
  2363.       Selects if you want an execute window (used by PRINT,  INPUT etc.) to
  2364.       be opened. If this window is not open, Comal will send it the Command
  2365.       Window (if open).
  2366.  
  2367.  
  2368.  
  2369.   3.6 The Program menu.
  2370.  
  2371.   Now we come to the importent Program menu:
  2372.  
  2373.  
  2374.     Control
  2375.       The program is scanned and the structure is checked. Modules  USEd by
  2376.       the program are loaded and initialized and finally all functions/proce-
  2377.       dures are made known so that  they can  be executed  from the command
  2378.       window.
  2379.  
  2380.     Execute
  2381.       Program execution starts. During execution the status line is changed to
  2382.       Program execution. It is possible to move around in the program buffer
  2383.       during program execution but no editing can be performed.
  2384.  
  2385.       It is also possible to open another project and start editing or execu-
  2386.       ting a new program.
  2387.  
  2388.     Stop Execution
  2389.       Program execution is stopped.
  2390.  
  2391.     Continue Execution
  2392.       A stopped program can be restarted.
  2393.  
  2394.  
  2395.                                          42
  2396.  
  2397.  
  2398.  
  2399.  
  2400.  
  2401.     Parameters (only Workbench 2.04 or higher)
  2402.       A special  window is  opened where  you can  enter startup parameters
  2403.       send to  to the  program before start. The form of the parameters are
  2404.       free. The parameters are stored in the Comal structure (see 10.1.2) in
  2405.       the same way as ToolTypes in code files and combined files are stored.
  2406.  
  2407.     Load
  2408.       A program stored by the Save item can be loaded.
  2409.  
  2410.     Save
  2411.       Store program buffer in code form. This should be used to store modu-
  2412.       les.
  2413.  
  2414.     Combine
  2415.       Combines the interpreter, the program and all modules into an execut-
  2416.       able file. A file requester will pop up and you may select the name of
  2417.       the output file.
  2418.  
  2419.     Show Modules
  2420.       A requester like a file requester shows all modules loaded. By selecting
  2421.       one of these modules you may see the content.
  2422.  
  2423.     Remove All Modules
  2424.       All modules loaded is removed.
  2425.  
  2426.     Trace Mode
  2427.       Toggle the trace (debugging) mode.
  2428.  
  2429.  
  2430.  
  2431.   3.7 The Trace menu.
  2432.  
  2433.   This last menu is only active if Trace Mode is on. It contains the following
  2434.   items:
  2435.  
  2436.     Execute One Step
  2437.       One programming step is executed. Then  all watch  expressions in the
  2438.       watch window is updated and control is returned to the editor with the
  2439.       cursor placed on the next line to be  executed (shown  in reverse pen
  2440.       color).
  2441.  
  2442.     Execute One Line
  2443.       One program  line is  executed. Procedures, functions and single line
  2444.       loops are executed. Then all watch expressions in the watch window is
  2445.       updated and control is returned to the editor with the cursor placed on
  2446.       the next line to be executed (shown in reverse pen color).
  2447.  
  2448.     Open Watch Window
  2449.       If you have closed the watch window by clicking on its close gadget it
  2450.       is re-opened.
  2451.  
  2452.                                          43
  2453.  
  2454.  
  2455.  
  2456.  
  2457.  
  2458.  
  2459.     New Watch Expressing
  2460.       A requester  will pop  up and you may enter an expression (like a va-
  2461.       riable, a function name or a more complicated expression). The expres-
  2462.       sion and its current value will be shown in the watch window and will
  2463.       be updated after each program step.
  2464.  
  2465.       A watch expression can  be removed  by double  clicking on  it in the
  2466.       watch window. You will be prompted to accept.
  2467.  
  2468.     Clear All Watches
  2469.       All watch expressions will be removed. You will be prompted to accept.
  2470.  
  2471.     Clear All Break Points
  2472.       All break points in the program will be removed. You will be prompted
  2473.       to accept.
  2474.  
  2475.  
  2476.   A break point is set by double clicking on a  program line  in the editor
  2477.   while being in trace mode. It is possible to set break points in modules,
  2478.   too.
  2479.  
  2480.   Concerning the use of the debugger see the tutorial chapter (section 7).
  2481.  
  2482.  
  2483.  
  2484.  
  2485.  
  2486.  
  2487.  
  2488.  
  2489.  
  2490.  
  2491.  
  2492.  
  2493.  
  2494.  
  2495.  
  2496.  
  2497.  
  2498.  
  2499.  
  2500.  
  2501.  
  2502.  
  2503.  
  2504.  
  2505.  
  2506.  
  2507.  
  2508.  
  2509.                                          44
  2510.  
  2511.  
  2512.  
  2513.  
  2514.  
  2515.   IV. DESCRIPTION OF THE Comal LANGUAGE
  2516.  
  2517.  
  2518.   1 Data types, variables and expressions.
  2519.  
  2520.   1.1 Identifiers.
  2521.  
  2522.   Identifiers are used as names of variables, functions, procedures etc.
  2523.  
  2524.   Examples of identifiers are:
  2525.  
  2526.     C   parity    Even    NewName    alfa1    get'key    prg_21
  2527.  
  2528.  
  2529.   An identifier consists of a letter eventually followed by a number of let-
  2530.   ters, digits, underscores (_) or single quotes ('). An identifier may have any
  2531.   length (in fact not longer than 255 characters, but who  would ever reach
  2532.   that limit?). Letters may be national letters such as the danish letters  , O
  2533.   and A.
  2534.  
  2535.   Identifiers may end with a number sign (#) or a dollar sign ($). Such iden-
  2536.   tifiers are used as names of integer or string variables or functions.
  2537.  
  2538.   Upper and lower case letters are destinct. These identifiers are different:
  2539.  
  2540.     newname     NewName   NEWNAME
  2541.  
  2542.  
  2543.   Some identifiers are reserved and are used either as names of predeclared
  2544.   functions or procedures or they are used as names of  Comal language key-
  2545.   words. Examples of reserved words are:
  2546.  
  2547.     sin    inkey$     IF     PROC     COS     ENDLOOP
  2548.  
  2549.  
  2550.   Reserved identifiers may be written in either upper or lower case letters.
  2551.   This means that both print and  PRINT are the  name  of  the  output key-
  2552.   word, but Print is not.
  2553.  
  2554.  
  2555.   1.2 Simple data types.
  2556.  
  2557.   Comal has  a few important data types built into the language. These data
  2558.   types are numbers and strings. Other data types may be defined by the pro-
  2559.   grammer (see the sections 1.3.2 and 1.5).
  2560.  
  2561.   Numbers may  be either integers or floats (reals). But normally you don't
  2562.   need to distinguish between integers and floats.
  2563.  
  2564.  
  2565.  
  2566.                                          45
  2567.  
  2568.  
  2569.  
  2570.  
  2571.  
  2572.   1.2.1 Constants.
  2573.  
  2574.   Integers
  2575.  
  2576.     The following numbers are examples of integers:
  2577.  
  2578.       123456    -852       0
  2579.  
  2580.     The integer data type is divided into different subtypes differing by the
  2581.     range of integers that can be the value of the type. These types are:
  2582.  
  2583.       type      integer range
  2584.  
  2585.       ULONG     0 ... 4294967295
  2586.  
  2587.       LONG      -2147483648 ... 214783647
  2588.  
  2589.       USHORT    0 ... 65535
  2590.  
  2591.       SHORT     -32768 ... 32767
  2592.  
  2593.       UBYTE     0 ... 255
  2594.  
  2595.       BYTE      -128 ... 127
  2596.  
  2597.  
  2598.     Integer constants may be written in either decimal, hexadecimal or binary
  2599.     format. Hexadecimal constants are preceded by a dollar sign ($) and bina-
  2600.     ry constants by a percent sign (%):
  2601.  
  2602.       $1234FED    $ABCD   $FFFFFFFF
  2603.       %010011     %111    %1000111101111110001
  2604.  
  2605.  
  2606.   Floats
  2607.  
  2608.     The float  number type is used to represent fractional numbers and num-
  2609.     bers of very large or very small magnitude.
  2610.  
  2611.     The float numbers are represented internally as floating  point (64 bit
  2612.     IEEE). This means that they have aproximately 16 digits of precision and
  2613.     a tens exponent in the range -308 to 308.
  2614.  
  2615.     Float constants may be written as normal numbers with a  single decimal
  2616.     point or in exponential notation:
  2617.  
  2618.       3.14159     123456.0     -852.3     0.00001
  2619.       3.52E-27    4756328E112   0.000123E-27
  2620.  
  2621.  
  2622.  
  2623.                                          46
  2624.  
  2625.  
  2626.  
  2627.  
  2628.  
  2629.   Strings
  2630.  
  2631.     A string is a sequence af characters (printable as well as non printable).
  2632.  
  2633.     A string  constant is  typed as  a sequence of characters surrounded by
  2634.     quotes ("):
  2635.  
  2636.       "This is a string containing 51 printable characters"
  2637.       "Comal"
  2638.       "123"
  2639.  
  2640.     A quotation mark is written using a double quote:
  2641.  
  2642.       "A ""double quote"" example"
  2643.  
  2644.     Non printable characters are written by  using its  ASCII number within
  2645.     quotation marks:
  2646.  
  2647.       "A bad error "7""
  2648.  
  2649.  
  2650.   1.2.2 Expressions.
  2651.  
  2652.   An expression consists of constants, variables, functions, parenthesis and
  2653.   operators that yield a new value.
  2654.  
  2655.  
  2656.   Expressions involving numbers
  2657.  
  2658.     Operators used in expressions involving numbers are:
  2659.  
  2660.                                       examples of use
  2661.  
  2662.         -     unary minus             -7  -3.14157
  2663.  
  2664.         ^     exponentiation          2^3 (=8)
  2665.  
  2666.         *     multiplication          5.2*7.1 (=36.92)
  2667.  
  2668.         /     division                4.8/3 (=1.6)
  2669.  
  2670.        MOD    modulo (remainder)      27 MOD 4 (=3)
  2671.  
  2672.        DIV    integer division        27 DIV 4 (=6)
  2673.  
  2674.         +     addition                4.56+5.77 (=10.33)
  2675.  
  2676.         -     subtraction             4.56-5.77 (=-1.21)
  2677.  
  2678.       BITAND  binary AND              %1101 BITAND %0110 (=%0100)
  2679.  
  2680.                                          47
  2681.  
  2682.  
  2683.  
  2684.  
  2685.  
  2686.  
  2687.       BITOR   binary OR               %1101 BITOR %0110 (=%1111)
  2688.  
  2689.       BITXOR  binary XOR              %1101 BITXOR %0110 (=%1011)
  2690.  
  2691.         <     less than               25<37 (=TRUE = 1)
  2692.  
  2693.        <=     less or equal           27<=27  (=TRUE)
  2694.  
  2695.         =     equal                   5=8 (=FALSE = 0)
  2696.  
  2697.        >=     greater or equal        -56>=56 (=FALSE)
  2698.  
  2699.         >     greater than            -33>-57 (=TRUE)
  2700.  
  2701.        <>     not equal to            44<>0 (=TRUE)
  2702.  
  2703.        NOT    logical NOT             NOT 44<>0 (=FALSE)
  2704.  
  2705.        AND    logical AND             44<>0 AND 5=8 (=FALSE)
  2706.  
  2707.        OR     logical OR              44<>0 AND 5=8 (=TRUE)
  2708.  
  2709.  
  2710.     The operators are listed in the order of their precedence. This precedence
  2711.     may be changed by using parenthesis:
  2712.  
  2713.        2+3*4    = 14
  2714.       (2+3)*4   = 20
  2715.  
  2716.  
  2717.     Before the  evaluation of an expression all integer types except ULONGs
  2718.     are changed to LONG. The type of the  result depends  on the  types and
  2719.     the operators in the expression according to the following table
  2720.  
  2721.      +------------------+------------------+------------------+
  2722.      |                  |                  |                  |
  2723.      |   left operand   |  right operand   |    result        |
  2724.      |                  |                  |                  |
  2725.      +------------------+------------------+------------------+
  2726.      |                  |                  |                  |
  2727.      |      FLOAT       |    any number    |    FLOAT         |
  2728.      |                  |                  |                  |
  2729.      |   any number     |      FLOAT       |    FLOAT         |
  2730.      |                  |                  |                  |
  2731.      |      LONG        |  LONG or ULONG   |     LONG         |
  2732.      |                  |                  |                  |
  2733.      |     ULONG        |  LONG or ULONG   |    ULONG         |
  2734.      |                  |                  |                  |
  2735.      +------------------+------------------+------------------+
  2736.  
  2737.                                  48
  2738.  
  2739.  
  2740.  
  2741.  
  2742.  
  2743.  
  2744.  
  2745.     The result of an expression involving division (/) is FLOAT.
  2746.  
  2747.     Normally all  parts of  an expression is evaluated. This means that the
  2748.     right parenthesis in
  2749.  
  2750.       (6-2*3)*(5+7)
  2751.  
  2752.     is evaluated even though the value of the expression is determined by the
  2753.     first parenthesis (which is zero).
  2754.  
  2755.     An important exception from this rule is expressions containing the logi-
  2756.     cal operators AND and OR. If the left operand of  an AND  expression is
  2757.     evaluated to  FALSE the  right operand is not evaluated and if the left
  2758.     operand of an OR expression is evaluated to TRUE, the  right operand is
  2759.     not evaluated. As an example the expression
  2760.  
  2761.       (25>37) AND (2=1/0)
  2762.  
  2763.     is evaluated to FALSE and it will not result in a run time error since the
  2764.     right expression is not evaluated.
  2765.  
  2766.     This evaluation rule for AND and OR simplifies a lot  of programming as
  2767.     the following example shows.
  2768.  
  2769.     Example: This  piece of  code can be used to find a given number n in a
  2770.       table of numbers Table()
  2771.  
  2772.         index:=MAXINDEX(Table())
  2773.         WHILE Index>0 AND n<>Table(index) DO
  2774.           index:=index-1
  2775.         ENDWHILE
  2776.  
  2777.       If the number is not found the value of index is zero.
  2778.  
  2779.  
  2780.     Note that there are no boolean type in Comal. Boolean expressions evalu-
  2781.     ates to 1 if they are true and they evaluates to 0 if they are false.
  2782.  
  2783.     Any number expression used as a boolean expression is considered false if
  2784.     it is zero and true otherwise.
  2785.  
  2786.  
  2787.  
  2788.   Expressions involving strings
  2789.  
  2790.     Operators in expressions involving strings are:
  2791.  
  2792.  
  2793.  
  2794.                                          49
  2795.  
  2796.  
  2797.  
  2798.  
  2799.  
  2800.                                     examples of use
  2801.  
  2802.       (..)  string selection        "strings"(3..6)  (= "ring")
  2803.  
  2804.        *    string repetition       3*"Comal" (="ComalComalComal")
  2805.  
  2806.        +    string concatenation    "some"+"times" (="sometimes")
  2807.  
  2808.        <    less than               "alf"<"alfa" (=TRUE)
  2809.  
  2810.       <=    less or equal           "abc"<="ABC"  (=FALSE)
  2811.  
  2812.        =    equal                   "some"="any" (=FALSE)
  2813.  
  2814.       >=    greater or equal        "2">="!"  (=TRUE)
  2815.  
  2816.        >    greater than            "Comal">"BASIC" (=TRUE)
  2817.  
  2818.       <>    not equal to            ""<>" " (=TRUE)
  2819.  
  2820.       IN    contained in            "me" IN "sometimes" (=3)
  2821.  
  2822.  
  2823.     Note that only the first three has string values. The remaining operators
  2824.     are used between strings but the value of the expression is a number.
  2825.  
  2826.     The selection operator (..) selects part of a string. The first character of
  2827.     the selected substring is the character with the position specified by the
  2828.     first number in the parenthesis and the last character in the substring is
  2829.     the character with the position specified by the last number.
  2830.  
  2831.     Example: The function DATE$ returns  the  current  date  in  the format
  2832.       yyyy-mm-dd. This  piece of code prints the current data in the format
  2833.       mm.dd.yy:
  2834.  
  2835.         PRINT DATE$(6..7),".",DATE$(9..10),"."DATE$(3..4)
  2836.  
  2837.  
  2838.     It is possible to omit the first or the last character position. In this case
  2839.     it is considered as 1 and the length of the string respectively:
  2840.  
  2841.         "sometimes"(..4)    = "some"
  2842.         "sometimes"(5..)    = "times"
  2843.  
  2844.     During evaluation of expressions involving the comparison oprators <, <=,
  2845.     =, >=, > and <>, the characters in the strings are compared  one by one
  2846.     using the ASCII value of the characters (or the value set in the sorting
  2847.     table - see section 10.1.2).
  2848.  
  2849.  
  2850.  
  2851.                                          50
  2852.  
  2853.  
  2854.  
  2855.  
  2856.  
  2857.     An IN expression evaluates to the first position of the left string operand
  2858.     in the right string operand (if it is part of this) and it evaluates to zero
  2859.     if the left operand is not part of the right operand.
  2860.  
  2861.     Note that since a non zero value is considered true if it is used  as a
  2862.     boolean value, an IN expression can be used as a boolean expression.
  2863.  
  2864.  
  2865.     Example: This  piece of  code can be used to get a "Yes/No"-answer from
  2866.       the user:
  2867.  
  2868.         PRINT "Yes or No (Y/N)? :",
  2869.         REPEAT
  2870.           Answ$:=INKEY$
  2871.         UNTIL Answ$ IN "YyNn"
  2872.         PRINT Answer$
  2873.  
  2874.  
  2875.   1.2.3 Variables.
  2876.  
  2877.   A variable is a location in the main memory used to hold a value of a cer-
  2878.   tain type. Such locations may be identified by a name (an identifier). Very
  2879.   often this name is identified as the variable itself.
  2880.  
  2881.   Since the variable is used to hold values of a certain type the size of the
  2882.   memory location depends on the type in question.
  2883.  
  2884.   Number variables
  2885.  
  2886.     Number variables  are declared  (memory is  reserved) in DIM statements
  2887.     like
  2888.  
  2889.       DIM Number OF FLOAT       // A floating point variable
  2890.       DIM n OF LONG, m OF LONG  // Two long integer variables
  2891.       DIM c OF UBYTE            // A variable of type UBYTE
  2892.  
  2893.  
  2894.     The general format of a number declaration DIM statement is
  2895.  
  2896.       DIM variablename [OF NumberType]
  2897.  
  2898.     where NumberType is one of  the  types  FLOAT,  ULONG,  ...  BYTE  or a
  2899.     user defined type (see 1.5). The default type is FLOAT.
  2900.  
  2901.     After the execution of a DIM statements the values of the declared vari-
  2902.     ables are zero. This value may be replaced by another value in assignment
  2903.     statements like:
  2904.  
  2905.       Number:=2.718281828       n:=-38
  2906.       m:=45+n                   c:=10
  2907.  
  2908.                                          51
  2909.  
  2910.  
  2911.  
  2912.  
  2913.  
  2914.  
  2915.     The general format of an assignment statement is:
  2916.  
  2917.       identifier:=expression
  2918.  
  2919.  
  2920.     The different number types may be mixed in expressions. Comal makes the
  2921.     necessary convertions between the types. If an integer variable is assig-
  2922.     ned the value of an expression with a floating point value, that value is
  2923.     rounded to the nearest integer value. If a value exceeds the range of the
  2924.     type, an error is reported by the Comal system.
  2925.  
  2926.     Floating point  and long  integer variables need not be declared before
  2927.     they are used. If the variable Alfa is not declared before its use, it is
  2928.     automatically created as a floating point variable (unless you have turned
  2929.     off automatic variable creation - see section III.3.6). If the variable i# is
  2930.     not declared before its use, it is automatically created as a long integer
  2931.     variable (the number sign # tells the system that it is a  long integer
  2932.     variable).
  2933.  
  2934.     The  value  of  number  variables  may be decremented or incremented in
  2935.     special assignment statements like:
  2936.  
  2937.       n:-7
  2938.       x:+3.2
  2939.  
  2940.     The effect of these statements are the same as the effect af the state-
  2941.     ments
  2942.  
  2943.       n:=n-7
  2944.       x:=x+3.2
  2945.  
  2946.     but they are executed a little bit faster.
  2947.  
  2948.  
  2949.   String variables
  2950.  
  2951.     String variables are used to hold string values. The name of a string va-
  2952.     riable always ends with a dollar sign ($). String variables are declared in
  2953.     DIM statements like:
  2954.  
  2955.       DIM Name$ OF 25   // A variable holding up to 25 characters
  2956.       DIM Answ$er OF 1  // A variable holding only one character
  2957.  
  2958.  
  2959.     In the declaration af a string variable the maximum length of the string
  2960.     value is specified. This maximum string length may be up to 32767. After
  2961.     the declaration the value of the string variable is set to the empty string
  2962.     (""). This value may be replaced by another value in  assignment state-
  2963.     ments like:
  2964.  
  2965.                                          52
  2966.  
  2967.  
  2968.  
  2969.  
  2970.  
  2971.  
  2972.       Name$:="Borge"
  2973.       Answer$:="y"
  2974.  
  2975.  
  2976.     If a string variable is assigned a string which is longer than the maximum
  2977.     length specified in the declaration statement, the string is truncated. For
  2978.     example:
  2979.  
  2980.       Answer$:="No" // The string "No" is truncated to "N"
  2981.  
  2982.     A string variable need not be declared before its use. If a string variable
  2983.     is not declared before it is used, the system will automatically reserve
  2984.     space for 80 characters.
  2985.  
  2986.     The value  of string  variables may be "incremented" by using a special
  2987.     assignment statement like
  2988.  
  2989.       Name$:+" Christensen"
  2990.  
  2991.  
  2992.     Part of a string variable may be assigned a new value by using the selec-
  2993.     tion operator:
  2994.  
  2995.       s$:="Comal is a programming language"
  2996.       s$(5..9):=": the"
  2997.  
  2998.  
  2999.     If the value of the new substring is longer than the selected string, the
  3000.     value is truncated. If it is shorter, spaces are added.
  3001.  
  3002.  
  3003.  
  3004.   1.3 Structured data types.
  3005.  
  3006.   A structured type is a single type built out of simple types in certain ways
  3007.   and given a single name. This section discuss indexed variables (arrays) and
  3008.   records (strucs). In a later section the class type, which is an extension of
  3009.   the record type, will be discussed.
  3010.  
  3011.  
  3012.   1.3.1 Indexed variables.
  3013.  
  3014.   An indexed variable is a sort of table of values all of the same type. The
  3015.   table may have one ore more dimensions.
  3016.  
  3017.   Indexed variables are declared in DIM statements where the number  of in-
  3018.   dicies (dimensions), the number of index values of each dimension and the
  3019.   type of the elements are specified:
  3020.  
  3021.  
  3022.                                          53
  3023.  
  3024.  
  3025.  
  3026.  
  3027.  
  3028.     DIM a(4,5) OF FLOAT
  3029.     DIM b(100) OF BYTE
  3030.     DIM t$(20) OF 30
  3031.  
  3032.   The first table a has two indicies. The first index may have the values 1,
  3033.   2, 3  and 4 and the second index may have the values 1,2,3,4,5. The total
  3034.   number of elements, which are all of type FLOAT, is 20.
  3035.  
  3036.   The second table b has only one index taking on values from 1 to 100. The
  3037.   elements are of type BYTE. The third array t$ has one index that can take
  3038.   on values from 1 to 20. Each element is a string with  the maximum length
  3039.   30.
  3040.  
  3041.   The number of indicies and the range of each index is limited only by the
  3042.   available memory. The specified type may be any type (including user defi-
  3043.   ned types) except pointer type and array type.
  3044.  
  3045.   The indicies may take on the values from 1 (lower bound) up to the speci-
  3046.   fied upper bound. It is possible to specify other index ranges:
  3047.  
  3048.     DIM a(0..3,0..4) OF FLOAT
  3049.     DIM b(-50..49) OF BYTE
  3050.     DIM t$(10..29) OF 30
  3051.  
  3052.   Here is both the upper and lower bound of the indicies specified. The num-
  3053.   ber of index values are the same as in the previous example.
  3054.  
  3055.   The upper  and lower  bounds of the index values can be examined by using
  3056.   the functions MAXINDEX and MININDEX:
  3057.  
  3058.     MININDEX(a())     returns 0
  3059.     MININDEX(a(),1)   returns 0   (same as MININDEX(a())
  3060.     MAXINDEX(a(),2)   returns 4
  3061.     MAXINDEX(t$())    returns 29
  3062.  
  3063.  
  3064.   Note that the second argument is optional. If not present the bounds of the
  3065.   first dimensions is returned.
  3066.  
  3067.   The individual elements of the table is referenced by using the name of the
  3068.   table followed by the indicies of the element in parenthesis:
  3069.  
  3070.     a(2,3):=11.27
  3071.     INPUT "Enter a number: ":b(35)
  3072.     t$(15):="blue"
  3073.     PRINT a(1,1)
  3074.  
  3075.   Each of the elements referenced in this way is treated like a  simple va-
  3076.   riable of the elements type, and they may replace simple variables at any
  3077.   time.
  3078.  
  3079.                                          54
  3080.  
  3081.  
  3082.  
  3083.  
  3084.  
  3085.  
  3086.   The whole table can be set equal to the same value in one statement:
  3087.  
  3088.     a(,):=111.11
  3089.     b():=27
  3090.     t$():="yellow"
  3091.  
  3092.  
  3093.   1.3.2 Strucs (records).
  3094.  
  3095.   A struc is a user defined type whose value is a collection of values that
  3096.   are (possibly) of different types (in contradiction to indexed variables).
  3097.  
  3098.   The struc type is defined in a STRUC statement which has the form:
  3099.  
  3100.     STRUC identifier
  3101.         :
  3102.  
  3103.       DIM statements
  3104.  
  3105.         :
  3106.     ENDSTRUC identifier
  3107.  
  3108.  
  3109.  
  3110.   The DIM  statements in  the struc definition has the same format as other
  3111.   DIM statements except that all size specifications (like the size of a string
  3112.   and index bounds) must be constants.
  3113.  
  3114.   Later an extension of the struc concept (classes) will be discussed.
  3115.  
  3116.   Example:
  3117.  
  3118.     STRUC Person
  3119.       DIM FirstName$ OF 20, LastName$ OF 20
  3120.       DIM Address$ OF 30, City$ OF 20
  3121.       DIM Age of UBYTE
  3122.     ENDSTRUC Person
  3123.  
  3124.   Note that a STRUC statement defines a new type. No variables are defined.
  3125.   This is done in the normal way using DIM statements.
  3126.  
  3127.   Example:
  3128.  
  3129.     DIM Person OF Person
  3130.     DIM Member OF Person
  3131.     DIM Club(100) OF Person
  3132.  
  3133.     Note that it is possible to use the same name for the variable as is used
  3134.     for the type.
  3135.  
  3136.                                          55
  3137.  
  3138.  
  3139.  
  3140.  
  3141.  
  3142.  
  3143.   The elements of the struc are called fields and are accessed using the name
  3144.   of the struc variable, a dot and the name of the field (the dot notation).
  3145.  
  3146.   Example:
  3147.  
  3148.     Person.FirstName$:="Len"
  3149.     INPUT "Last name: ": Member.LastName$
  3150.     PRINT Club(35).Age
  3151.  
  3152.  
  3153.   A struc may be assigned the value of another struc in an assignment state-
  3154.   ment.
  3155.  
  3156.   Example:
  3157.     Member:=Club(35)
  3158.     Club():=Person
  3159.  
  3160.  
  3161.   1.4 Dynamic variables. Pointer variables.
  3162.  
  3163.   Any variable  that is  to be used in a program needs two things. It needs
  3164.   storage in the main memory to store the value of the variable and it needs
  3165.   some means of identification. A declaration like
  3166.  
  3167.     DIM Alfa OF UBYTE
  3168.  
  3169.   meets both this needs. It creates a variable (reserves storage in main me-
  3170.   mory) and it identifies this variable by the name Alfa.
  3171.  
  3172.   There is another more indirect way of creating and identifying a variable.
  3173.   In the declaration
  3174.  
  3175.     DIM p OF POINTER TO UBYTE
  3176.  
  3177.   a variable p is created. The value of this variable is not itself of type
  3178.   UBYTE. In stead the value is the identifier of a variable of type UBYTE.
  3179.  
  3180.   A variable is in fact a memory location in the main memory.  Such a loca-
  3181.   tion has an address. This address can be identified by a name (that's what
  3182.   we have used until now) or it can be identified by a number (in our daily
  3183.   life addresses  are mixtures  of names and numbers). In our newly created
  3184.   variable the address of the UBYTE variable is identified by  a number. If
  3185.   you execute the statement
  3186.  
  3187.     PRINT p
  3188.  
  3189.   you will get this number. It turns out to be zero which is synonymous for
  3190.   no address. There is no address since the UBYTE variable has not yet been
  3191.   created.
  3192.  
  3193.                                          56
  3194.  
  3195.  
  3196.  
  3197.  
  3198.  
  3199.  
  3200.   This can be done in a statement like
  3201.  
  3202.     ALLOCATE(p)
  3203.  
  3204.  
  3205.   Now the statement
  3206.  
  3207.     PRINT p
  3208.  
  3209.   will give a non zero address.
  3210.  
  3211.   The value of the UBYTE variable is accessed by using the indirection opra-
  3212.   tor @ as shown in the following statements
  3213.  
  3214.     p@:=5
  3215.     p@:+7
  3216.     PRINT p@+27
  3217.  
  3218.  
  3219.   As you see p@ is a normal variable (of type UBYTE).
  3220.  
  3221.   In the statement
  3222.  
  3223.     ALLOCATE(p)
  3224.  
  3225.   the procedure ALLOCATE reserves space for the variable  p@ among  all the
  3226.   other variables  used in  the program. The ALLOCATE procedure may also be
  3227.   called with two parameters:
  3228.  
  3229.     ALLOCATE(p,MemType)
  3230.  
  3231.  
  3232.   If this form is used the memory is allocated in the storage administrated by
  3233.   the Amiga operating system. The value of MemType can be:
  3234.  
  3235.       MEMF_PUBLIC (=1)
  3236.       MEMF_CHIP   (=2)
  3237.       MEMF_FAST   (=4)
  3238.  
  3239.  
  3240.   Normally  you  will  use  MEMF_PUBLIC.  This  name  as  well as the names
  3241.   MEMF_CHIP and MEMF_FAST are defined in the System module.
  3242.  
  3243.   The memory allocated by the  procedure  ALLOCATE  can  be  deallocated by
  3244.   the statement
  3245.  
  3246.     DEALLOCATE(p)
  3247.  
  3248.  
  3249.  
  3250.                                          57
  3251.  
  3252.  
  3253.  
  3254.  
  3255.  
  3256.   After the execution of this statement the value of p is again zero (which
  3257.   means no address).
  3258.  
  3259.   A variable created by the procedure  ALLOCATE is  created during  the ex-
  3260.   ecution of the program and is therefore called a dynamic variable. The va-
  3261.   riable p itself is called a pointer variable since the value of p points to a
  3262.   variable.
  3263.  
  3264.   The general format of the declaration af a pointer variable is
  3265.  
  3266.     DIM varname OF POINTER TO typename
  3267.     DIM varname@ OF typename            // Short form
  3268.  
  3269.   where typename can be any type except a pointer type (see next section).
  3270.  
  3271.   Normally the  type pointed  at (typename above) has to be known, i.e. the
  3272.   type must be defined somewhere else in the program or it must be imported
  3273.   from a module. Exception from that rule are pointers that are fields in a
  3274.   structure. In this case the type pointed at is set to unknown pointer if it
  3275.   is not defined.
  3276.  
  3277.   If a  structure with  unknown pointer types is imported from a module the
  3278.   system looks for the  type in  the program  environment that  imports the
  3279.   structure and changes the unknown pointer type to the correct type if it is
  3280.   found. Otherwise the type will contiue to be unknown pointer.
  3281.  
  3282.   It is not possible to use the indirection operator on a pointer with unknown
  3283.   pointer type.
  3284.  
  3285.  
  3286.   Example: To write a text directly into an intuition window a structure of
  3287.     the following is used
  3288.  
  3289.       STRUC IntuiText
  3290.         DIM FrontPen OF UBYTE
  3291.         DIM BackPen OF UBYTE
  3292.         DIM DrawMode OF UBYTE
  3293.         DIM LeftEdge OF SHORT
  3294.         DIM TopEdge OF SHORT
  3295.         DIM ITextFont OF POINTER TO TextAttr
  3296.         DIM IText OF POINTER TO UBYTE
  3297.         DIM NextText OF POINTER TO IntuiText
  3298.       ENDSTRUC IntuiText
  3299.  
  3300.  
  3301.     If the type TextAttr is not defined elsewhere the pointer type is set to
  3302.     unknown pointer.
  3303.  
  3304.  
  3305.  
  3306.  
  3307.                                          58
  3308.  
  3309.  
  3310.  
  3311.  
  3312.  
  3313.   Example: In the module System the ComalStruc structure is defined (se sec-
  3314.     tion 10.1.2). One of the fields of this structure is:
  3315.  
  3316.       DIM CommPort OF POINTER TO MsgPort
  3317.  
  3318.     The type MsgPort is not known in the  module and  the type  of CommPort
  3319.     is unknown pointer.
  3320.  
  3321.     If you want to use this field you have to import the module PortObjects
  3322.     along with the module System:
  3323.  
  3324.       USE PortObjects
  3325.       USE System
  3326.  
  3327.  
  3328.   A pointer variable acts in many cases like a variable of type ULONG. It has
  3329.   a value (an address) of type ULONG, that may be used in any expression. It
  3330.   is also possible to assign a value to a pointer variable using an assignment
  3331.   statement:
  3332.  
  3333.     p:=$0004
  3334.  
  3335.  
  3336.   Such an  assignment can be dangerous since you are now able to change any
  3337.   portion of the memory in your Amiga. To avoid mistakes  you can  only as-
  3338.   sign an  expression of type ULONG to a pointer. In this way most mistakes
  3339.   will be caught by the system because ULONG  values are  difficult to make
  3340.   (see description of expressions).
  3341.  
  3342.   Example:  The  function  in  this  example  implements  the PEEK function
  3343.     known from many BASIC dialects
  3344.  
  3345.  
  3346.         FUNC peek(MemPtr OF UbytePtr) OF UBYTE
  3347.           RETURN MemPtr@
  3348.         ENDFUNC peek
  3349.  
  3350.         TYPE UbytePtr=POINTER TO UBYTE
  3351.  
  3352.  
  3353.   Example: The following program fraction shows the use of pointers  in the
  3354.     creation of a linked list:
  3355.  
  3356.  
  3357.           :
  3358.           :
  3359.  
  3360.         STRUC Person
  3361.           DIM Next OF POINTER TO Person
  3362.           DIM Name$ OF 30
  3363.  
  3364.                                          59
  3365.  
  3366.  
  3367.  
  3368.  
  3369.  
  3370.           DIM Address$ OF 30
  3371.           DIM City$ OF 20
  3372.           DIM Age of UBYTE
  3373.         ENDSTRUC Person
  3374.  
  3375.         DIM Start OF POINTER TO Person
  3376.         DIM Node OF POINTER TO Person
  3377.  
  3378.           :
  3379.           :
  3380.  
  3381.         // Insert the variable Person@ in the list
  3382.  
  3383.         IF Start=0 THEN
  3384.           Start:=Person
  3385.         ELSE
  3386.           Node:=Start
  3387.           IF Start@.Name$<Person@.Name$ THEN
  3388.             WHILE Node@.Next AND Node@.Next@.Name$<Person@.Name$
  3389.               Node:=Node@.Next
  3390.             ENDWHILE
  3391.           ENDIF
  3392.           Person@.Next:=Node@.Next
  3393.           Node@.Next:=Person
  3394.         ENDIF
  3395.  
  3396.           :
  3397.           :
  3398.  
  3399.  
  3400.   A pointer  variable can  be used as a one dimensional indexed variable by
  3401.   placing an index value after the  variable name.  The range  of the index
  3402.   values is all non negative integers.
  3403.  
  3404.  
  3405.   Example: An  array of  100 elements  of type Person can be made by execu-
  3406.     ting the statements
  3407.  
  3408.       DIM Pers OF POINTER TO Person
  3409.  
  3410.       Pers:=malloc(100*SIZE(Person),MEMF_PUBLIC)
  3411.  
  3412.     and you can get one of the elements in this way:
  3413.  
  3414.       Pers(23).Name$="Donald E. Knut"
  3415.  
  3416.  
  3417.   This way of indexing into a dynamic variable can be very useful in connec-
  3418.   tion with some of the system routines.
  3419.  
  3420.  
  3421.                                          60
  3422.  
  3423.  
  3424.  
  3425.  
  3426.  
  3427.  
  3428.   1.5 Type definition.
  3429.  
  3430.   New types  are defined  in a  STRUC statement.  But new types may also be
  3431.   defined in a TYPE  statement. The  TYPE statement  can take  on different
  3432.   forms.
  3433.  
  3434.  
  3435.   TYPE NewType=OldType
  3436.  
  3437.     By using  this form  of the TYPE statement no new type is created. It's
  3438.     only new names for existing types.
  3439.  
  3440.     Examples:
  3441.  
  3442.       TYPE UWORD=USHORT
  3443.       TYPE WORD=SHORT
  3444.       TYPE BOOL=BYTE
  3445.  
  3446.  
  3447.   TYPE PtrType=POINTER TO Type
  3448.  
  3449.     This form of the TYPE statement is used to create a pointer type.
  3450.  
  3451.     Examples:
  3452.       TYPE UbytePtr=POINTER TO UBYTE
  3453.       TYPE WordPtr=POINTER TO WORD
  3454.       TYPE PersonPtr=POINTER TO Person
  3455.       TYPE WdPtr=POINTER TO Window
  3456.  
  3457.   TYPE AryType=ARRAY(dimension list) OF Type
  3458.  
  3459.     This form of the TYPE statement is used  to create  an array  type. The
  3460.     dimension list has the same form as discussed in the description of the
  3461.     DIM statement in section 1.3.1 (Indexed variables) except that only con-
  3462.     stant may be used.
  3463.  
  3464.     Examples:
  3465.       TYPE IntArray=ARRAY(0..5,-2..10) OF LONG
  3466.       TYPE Data=ARRAY(0..150000) OF UBYTE
  3467.       TYPE String10=ARRAY(0..10) OF UBYTE
  3468.  
  3469.  
  3470.     Having made these type definitions a pointer to (for example) a variable
  3471.     of type Data can be declared and a large array of bytes can be created:
  3472.  
  3473.       DIM DataPtr OF POINTER TO Data
  3474.       ALLOCATE(DataPtr,MEMF_PUBLIC)
  3475.  
  3476.  
  3477.  
  3478.                                          61
  3479.  
  3480.  
  3481.  
  3482.  
  3483.  
  3484.   TYPE FncType=FUNC[(parameter type list)] [OF NumberType]
  3485.   TYPE PrcType=PROC[(parameter type list)]
  3486.  
  3487.     These forms of the TYPE statement is used to create function and proce-
  3488.     dure types. This is necessary if you want to make functions or procedures
  3489.     with such parameter types. The terms inside the square brackets are op-
  3490.     tional.
  3491.  
  3492.     Examples:
  3493.       TYPE FltFunc=FUNC(FLOAT) OF FLOAT
  3494.       TYPE ByteFnc=FUNC OF BYTE
  3495.       TYPE ExceptProc=PROC(ULONG)
  3496.  
  3497.  
  3498.     Example: In  this program an integral function is made and the integral
  3499.       of the function sin from 0 to pi is printed out:
  3500.  
  3501.         PRINT integral(SIN(),0,PI)
  3502.  
  3503.         FUNC integral(f OF FltFunc,a,b)
  3504.           LOCAL n, dx, xi, s
  3505.           n:=16; dx:=(b-a)/n;
  3506.           xi:=a; s:=(f(a)-f(b))*dx/6
  3507.           LOOP n TIMES xi:=xi+dx; s:=s+(f(xi)+2*f(xi-dx/2))*dx/3
  3508.           RETURN s
  3509.         ENDFUNC integral
  3510.  
  3511.         TYPE FltFunc=FUNC(FLOAT) OF FLOAT
  3512.  
  3513.  
  3514.   TYPE statements may be  placed in  the main  program, in  closed procedu-
  3515.   res/functions or in modules. The program execution speed is not affected by
  3516.   the use of new type names. All type references are resolved at  the scan-
  3517.   ning time.
  3518.  
  3519.   The search for a matching type is done in this way:
  3520.  
  3521.     1.  The scanner  searches for  the name  in the same program level (the
  3522.         same procedure/function, module or the main program).
  3523.  
  3524.     2.  Then the name is searched for in the  modules used  in this program
  3525.         level.
  3526.  
  3527.     3.  Then the  name is  searched for  in lower  program levels (the main
  3528.         program or a procedure if the current procedure is local) or in modu-
  3529.         les used in these lower levels.
  3530.  
  3531.   If the  name cannot  be found the scanner will stop with an error message
  3532.   and the cursor will be placed on the unknown type name.
  3533.  
  3534.  
  3535.                                          62
  3536.  
  3537.  
  3538.  
  3539.  
  3540.  
  3541.  
  3542.   2 Program flow control statements.
  3543.  
  3544.   This section discuss the program statements that can be used to direct the
  3545.   program's sequence of execution ("flow control statements").
  3546.  
  3547.  
  3548.   2.1 Selection.
  3549.  
  3550.   Comal provides several forms of decision-making statements: the IF state-
  3551.   ments and the CASE statement.
  3552.  
  3553.  
  3554.   2.1.1 The IF statements.
  3555.  
  3556.   More than five variants of the IF statement are available, depending upon
  3557.   the use of ELSE and ELIF.
  3558.  
  3559.  
  3560.   Single line IF - THEN
  3561.  
  3562.     The single line IF statement has the form:
  3563.  
  3564.       IF condition THEN simple_statement
  3565.  
  3566.     where condition  is a number expression whose value is interpreted as a
  3567.     boolean value and simple_statement is any  non declaration  single line
  3568.     statement (except single line IF). If the condition is fulfilled the state-
  3569.     ment after THEN is executed.
  3570.  
  3571.     Examples:
  3572.  
  3573.       IF Printer$="Y" THEN SELECT OUTPUT "lp:"
  3574.  
  3575.       IF x>Max THEN Max:=x
  3576.  
  3577.  
  3578.   IF - THEN - ENDIF
  3579.  
  3580.     This is the simplest form of the multy  line IF  statement. The general
  3581.     format is:
  3582.  
  3583.       IF condition THEN
  3584.         statements
  3585.       ENDIF
  3586.  
  3587.     If the condition is fulfilled the statement(s) between the IF-THEN line
  3588.     and the ENDIF line is executed. If the condition is not fulfilled, then
  3589.     these lines  are skipped, and the program execution continues after the
  3590.     ENDIF line.
  3591.  
  3592.                                          63
  3593.  
  3594.  
  3595.  
  3596.  
  3597.  
  3598.  
  3599.     Example: In the following example an Intuition window is opened. If the
  3600.       operation fails (Window pointer is zero) an error message is printed and
  3601.       the program stops:
  3602.  
  3603.         Window=OpenWindow(ADR(NewWindow))
  3604.         IF Window=0 THEN
  3605.           PRINT "Window could not be opened"
  3606.           STOP
  3607.         ENDIF
  3608.  
  3609.  
  3610.  
  3611.   IF - THEN - ELSE - ENDIF
  3612.  
  3613.     The general format of this variation of the IF statement is:
  3614.  
  3615.       IF condition THEN
  3616.         statements
  3617.       ELSE
  3618.         statements
  3619.       ENDIF
  3620.  
  3621.     The statement(s) between the IF-THEN line and the ELSE line is executed
  3622.     if the condition is fulfilled, while the statement(s) between the ELSE line
  3623.     and the ENDIF line is executed if the condition is not satisfied. continues
  3624.     after the  ENDIF line. One of the statement segments will always be ex-
  3625.     ecuted, but never both. When the selected segment has been executed the
  3626.     program execution continues after the ENDIF line.
  3627.  
  3628.  
  3629.     Example:
  3630.  
  3631.       IF Printer$="Y" THEN
  3632.         SELECT OUTPUT "lp:"
  3633.       ELSE
  3634.         PAGE  // Clear screen
  3635.       ENDIF
  3636.  
  3637.  
  3638.   IF - THEN - ELIF - ENDIF
  3639.  
  3640.     The simplest form of this variation of the IF statement is:
  3641.  
  3642.       IF condition THEN
  3643.         statements
  3644.       ELIF condition THEN
  3645.         statements
  3646.       ENDIF
  3647.  
  3648.  
  3649.                                          64
  3650.  
  3651.  
  3652.  
  3653.  
  3654.  
  3655.  
  3656.     The ELIF (else if) condition is examined if and only if the IF condition is
  3657.     not satisfied. An arbitrary number of ELIF statements may be  placed in
  3658.     the IF-statement, for instance:
  3659.  
  3660.       IF condition THEN
  3661.         statements
  3662.       ELIF condition THEN
  3663.         statements
  3664.       ELIF condition THEN
  3665.         statements
  3666.       ELIF condition THEN
  3667.         statements
  3668.       ENDIF
  3669.  
  3670.  
  3671.     The conditions are examined one by one until one is fulfilled or there is
  3672.     no more ELIF lines. If a condition is fulfilled the statement(s) between
  3673.     the corresponding  IF/ELIF and  the next  ELIF/ENDIF is executed. After
  3674.     that the remainig conditions and statements are skipped, and the program
  3675.     execution continues after the ENDIF line. If none of conditions are ful-
  3676.     filed, then no statements are executed, and the  program execution con-
  3677.     tinues after the ENDIF line.
  3678.  
  3679.  
  3680.     Example:
  3681.  
  3682.       IF x>Max THEN
  3683.         Max:=x
  3684.       ELIF x<Min THEN
  3685.         Min:=x
  3686.       ENDIF
  3687.  
  3688.  
  3689.  
  3690.   IF - THEN - ELIF - ELSE - ENDIF
  3691.  
  3692.     The simplest form of this variation of the IF statement is:
  3693.  
  3694.       IF condition THEN
  3695.         statements
  3696.       ELIF condition THEN
  3697.         statements
  3698.       ELSE
  3699.         statements
  3700.       ENDIF
  3701.  
  3702.  
  3703.     An arbitrary  number of  ELIF statements may be placed in the IF-state-
  3704.     ment, for instance:
  3705.  
  3706.                                          65
  3707.  
  3708.  
  3709.  
  3710.  
  3711.  
  3712.  
  3713.       IF condition THEN
  3714.         statements
  3715.       ELIF condition THEN
  3716.         statements
  3717.       ELIF condition THEN
  3718.         statements
  3719.       ELIF condition THEN
  3720.         statements
  3721.       ELSE
  3722.         statements
  3723.       ENDIF
  3724.  
  3725.     The conditions are examined one by one until one is fulfilled or there is
  3726.     no more ELIF lines. If a condition is fulfilled the statement(s) between
  3727.     the corresponding IF/ELIF and the  next  ELIF/ELSE  is  executed. After
  3728.     that the  remainig part of the IF statement is skipped, and the program
  3729.     execution continues after the ENDIF line. If none of conditions are ful-
  3730.     filed, then the statements between ELSE and ENDIF will be executed.
  3731.  
  3732.     Example: This  program section  prints the  solution of a second degree
  3733.       equation (with coefficients A, B and C)
  3734.  
  3735.         D:=B^2-4*A*C    // The discriminant is calculated
  3736.         IF D<0 THEN
  3737.           PRINT "No solution"
  3738.         ELIF D=0 THEN
  3739.           PRINT "There is one solution:";-B/(2*A)
  3740.         ELSE
  3741.           x1:=(-B-SQR(D))/(2*A)
  3742.           x2:=(-B+SQR(D))/(2*A)
  3743.           PRINT "There are two solutions:";x1;"and";x2
  3744.         ENDIF
  3745.  
  3746.  
  3747.  
  3748.   2.1.2 The CASE statement.
  3749.  
  3750.     With a CASE statement it is possible to provide multiple branching. The
  3751.     general form of the statement is:
  3752.  
  3753.       CASE expression OF
  3754.       WHEN expression_list
  3755.         statements
  3756.       WHEN expression_list
  3757.         statements
  3758.       WHEN expression_list
  3759.         statements
  3760.       WHEN expression_list
  3761.         statements
  3762.  
  3763.                                          66
  3764.  
  3765.  
  3766.  
  3767.  
  3768.  
  3769.  
  3770.         :
  3771.  
  3772.       OTHERWISE
  3773.         statements
  3774.       ENDCASE
  3775.  
  3776.  
  3777.     An arbitrary  number of  WHEN options  can be  used. The OTHERWISE part
  3778.     is optional.
  3779.  
  3780.     When the CASE expression has been evaluated, it  will be  compared with
  3781.     each of the values specified in the first WHEN branch. If one of the val-
  3782.     ues agrees with the CASE expression, then the following statement (until
  3783.     next  WHEN/OTHERWISE/ENDCASE)   will  be   executed,  and  the  program
  3784.     execution will continue after ENDCASE.
  3785.  
  3786.     Each WHEN branch expression in the CASE statement  will be  examined in
  3787.     the order  in which  they occur.  The first  WHEN segment  for which an
  3788.     agreement is found will  be executed.  The remaining  part of  the CASE
  3789.     statement will be skipped, and the program execution will continue after
  3790.     ENDCASE.
  3791.  
  3792.     If none of the WHEN branch values agree  with the  CASE expression, the
  3793.     statement(s)  after  OTHERWISE  (if  present)  will  be executed. If no
  3794.     OTHERWISE part is present and none  of  the  WHEN  branch  values agree
  3795.     with the CASE expression, and error message will be generated.
  3796.  
  3797.  
  3798.     Example:
  3799.  
  3800.       CASE month$ OF
  3801.       WHEN "jan","mar","may","jul","aug","oct","dec"
  3802.         days:=31
  3803.       WHEN "apr","jun","sep","nov"
  3804.         days:=30
  3805.       WHEN "feb"
  3806.         days:=28    // No leap year support
  3807.       ENDCASE
  3808.  
  3809.  
  3810.     The type  of the  WHEN branch  values must  be the  same as the type of
  3811.     the CASE expression (string or number).
  3812.  
  3813.  
  3814.  
  3815.   2.2 Repetition.
  3816.  
  3817.   In Comal there are several forms  of repetive  statements: REPEAT, WHILE,
  3818.   FOR and LOOP.
  3819.  
  3820.                                          67
  3821.  
  3822.  
  3823.  
  3824.  
  3825.  
  3826.  
  3827.  
  3828.   REPEAT - UNTIL
  3829.  
  3830.     This repetive statement allows groups of statements to be executed again
  3831.     and again, until some terminating UNTIL condition is fulfilled.
  3832.  
  3833.     The general format of the statement is
  3834.  
  3835.       REPEAT
  3836.         statements
  3837.       UNTIL condition
  3838.  
  3839.     Since the the statements are executed before the condition is evaluated,
  3840.     the statements will always be executed at least once.
  3841.  
  3842.     Example:
  3843.  
  3844.       REPEAT
  3845.         CURSOR 5,10
  3846.         PRINT ""155"K",   // Erase to end of line
  3847.         INPUT "Enter number of disks (between 1 and 10): ": Num
  3848.       UNTIL Num>=1 AND Num<=10
  3849.  
  3850.  
  3851.  
  3852.   WHILE - ENDWHILE
  3853.  
  3854.     The  WHILE  statement  is  similar  to the REPEAT statement. It is used
  3855.     when a block of statements is to be  executed repeatedly  as long  as a
  3856.     particular condition is fulfilled. The major difference is that the condition
  3857.     is evaluated and tested before any statements inside the WHILE-block is
  3858.     executed.
  3859.  
  3860.     The general format of the WHILE statement is:
  3861.  
  3862.       WHILE condition DO
  3863.         statements
  3864.       ENDWHILE
  3865.  
  3866.     If the  condition is fulfilled, then the statement(s) between the WHILE
  3867.     line and ENDWHILE line is executed, and the condition will then be eval-
  3868.     uated again.
  3869.  
  3870.     If the condition is not satisfied, then the statement block is skipped and
  3871.     the program execution will continue after the ENDWHILE line.
  3872.  
  3873.  
  3874.     Example: This little program will print the content of a text file on the
  3875.       screen
  3876.  
  3877.                                          68
  3878.  
  3879.  
  3880.  
  3881.  
  3882.  
  3883.  
  3884.  
  3885.         OPEN FILE 1,"TextFile",READ
  3886.         WHILE NOT EOF(1) DO
  3887.           INPUT FILE 1: Line$
  3888.           PRINT Line$
  3889.         ENDWHILE
  3890.         CLOSE FILE 1
  3891.  
  3892.  
  3893.   Single line WHILE
  3894.  
  3895.     If only a single statement follows the WHILE line, then the statement can
  3896.     be placed in a single line WHILE.
  3897.  
  3898.     The format of a single line WHILE is:
  3899.  
  3900.       WHILE condition DO statement
  3901.  
  3902.     where simple_statement is any non declaration single line statement.
  3903.  
  3904.     Example: This line waits for a key to be pressed without using CPU time:
  3905.  
  3906.         WHILE KEY$<>"" DO WAIT
  3907.  
  3908.  
  3909.  
  3910.   FOR - ENDFOR
  3911.  
  3912.     The FOR statement is used if a group of statements are to be executed a
  3913.     certain number  of times with given counter values. The number of times
  3914.     the statement block is to be executed, is determined by means of a con-
  3915.     trol variable (the counter).
  3916.  
  3917.     The general format is
  3918.  
  3919.       FOR counter:=start TO end [STEP interval] DO
  3920.         statements
  3921.       ENDFOR counter
  3922.  
  3923.     The FOR statement contains an indication of the start and end values of
  3924.     the control variable. The statement block is executed until the control
  3925.     variable exceeds the the end value.
  3926.  
  3927.     When the group of statements has been executed, the control variable is
  3928.     changed. How much it is changed can be specified by  means of  the STEP
  3929.     option. If this option is omitted, then the control variable will be incre-
  3930.     mented by 1. After the change of the control variable the value is com-
  3931.     pared with the end value.
  3932.  
  3933.  
  3934.                                          69
  3935.  
  3936.  
  3937.  
  3938.  
  3939.  
  3940.     The first  time the value is surpassed, the FOR loop is completed , and
  3941.     the program execution continues after the ENDFOR line.
  3942.  
  3943.  
  3944.     Example:
  3945.  
  3946.       FOR i:=1 TO MaxMember DO
  3947.         PRINT Club(i).LastName$,", ",Club(i).FirstName$
  3948.         PRINT Club(i).Address$
  3949.         PRINT Club(i).City$
  3950.         PRINT
  3951.       ENDFOR i
  3952.  
  3953.  
  3954.   Single line FOR
  3955.  
  3956.     If only a single statement follows the FOR line, then the statement can
  3957.     be placed in a single line FOR.
  3958.  
  3959.     The format of a single line FOR is:
  3960.  
  3961.       FOR counter:=start TO end [STEP interval] DO statement
  3962.  
  3963.     where statement is any non declaration single line statement.
  3964.  
  3965.     Example:
  3966.  
  3967.       FOR x:=0 TO 6.3 STEP 0.1 DO PRINT x;COS(x);SIN(x)
  3968.  
  3969.  
  3970.  
  3971.   LOOP - TIMES - ENDLOOP
  3972.  
  3973.     The LOOP  statement is used if a group of statements are to be executed
  3974.     a certain number of times and you do not need a counter variable.
  3975.  
  3976.     The general format is:
  3977.  
  3978.       LOOP number TIMES
  3979.         statements
  3980.       ENDLOOP
  3981.  
  3982.  
  3983.     The statements are executed number times  before the  program execution
  3984.     continues after the ENDLOOP line.
  3985.  
  3986.     This loop  statement is  executed considerably faster than the FOR loop
  3987.     because of the lack of the counter variable.
  3988.  
  3989.  
  3990.  
  3991.                                          70
  3992.  
  3993.  
  3994.  
  3995.  
  3996.  
  3997.     Example:
  3998.  
  3999.       LOOP 4 TIMES
  4000.         forward(80)
  4001.         right(90)
  4002.       ENDLOOP
  4003.  
  4004.  
  4005.   Single line LOOP
  4006.  
  4007.     If only a single statement follows the LOOP-TIMES line, then the state-
  4008.     ment can be placed in a single line LOOP.
  4009.  
  4010.     The format of a single line LOOP is:
  4011.  
  4012.       LOOP number TIMES simple_statement
  4013.  
  4014.     where simple_statement is any non declaration single line statement.
  4015.  
  4016.     Example:
  4017.  
  4018.       t$:=""
  4019.       LOOP 30 TIMES t$:+"*"
  4020.  
  4021.  
  4022.   Endless LOOP
  4023.  
  4024.     This is  the simplest of all the repetive statements. It is used when a
  4025.     block of statements is to be executed an infinite number of times.
  4026.  
  4027.     The format of the statemet is
  4028.  
  4029.       LOOP
  4030.         statements
  4031.       ENDLOOP
  4032.  
  4033.     Example: The following piece of code is a typical main  part of  a menu
  4034.       driven program
  4035.  
  4036.         LOOP
  4037.           PAGE
  4038.           PRINT AT 7,10: "Create"
  4039.           PRINT AT 9,10: "Delete"
  4040.           PRINT AT 11,10: "Write"
  4041.           PRINT AT 15,10: "Select job: ",
  4042.           job$:=PressKey$("CcDdWw")
  4043.           CASE job$ OF
  4044.           WHEN "C","c"
  4045.             Create
  4046.           WHEN "D","d"
  4047.  
  4048.                                          71
  4049.  
  4050.  
  4051.  
  4052.  
  4053.  
  4054.             Delete
  4055.           WHEN "W","p"
  4056.             Write
  4057.           ENDCASE
  4058.         ENDLOOP
  4059.  
  4060.  
  4061.     The loop can be terminated by executing one of the branching statements
  4062.     (GOTO, IF .. GOTO, EXIT, EXIT WHEN ..).
  4063.  
  4064.  
  4065.  
  4066.   2.3 Branching.
  4067.  
  4068.   Branching means changing a program's flow of control by some  means other
  4069.   than the  statements described in the sections 2.1 and 2.2. There are two
  4070.   such branching statements: the GOTO statement and the EXIT statement.
  4071.  
  4072.  
  4073.   2.3.1 The GOTO statement.
  4074.  
  4075.   The GOTO statement is used to redirect execution  to another  part of the
  4076.   program. The new location is specified by a label.
  4077.  
  4078.   The general format of a GOTO statement is:
  4079.  
  4080.     GOTO label
  4081.  
  4082.  
  4083.   The format of a label line is:
  4084.  
  4085.     label:
  4086.  
  4087.   where label is an identifier. Note the colon (:) after the label name.
  4088.  
  4089.   The GOTO  statement is  not often  used, because of the presence of other
  4090.   flexible structures like the other program flow statements discussed in sec-
  4091.   tion 2.1 and 2.2. But there are times (usually error conditions) when it is
  4092.   the least painful way to break out of a number  of nested  program struc-
  4093.   tures.
  4094.  
  4095.  
  4096.     Example:
  4097.  
  4098.       Window=OpenWindow(ADR(NewWindow))
  4099.       IF Window=0 THEN
  4100.         PRINT "Window could not be opened"
  4101.         GOTO CleanUp
  4102.       ENDIF
  4103.  
  4104.  
  4105.                                          72
  4106.  
  4107.  
  4108.  
  4109.  
  4110.  
  4111.  
  4112.  
  4113.   2.3.1 The EXIT statement.
  4114.  
  4115.   The EXIT statement is used in any of the repetive statements to cause con-
  4116.   ditional or unconditional interrupt of the loop. When EXIT has been execu-
  4117.   ted, the program execution continues after the end of the loop.
  4118.  
  4119.   The format of an EXIT statement is:
  4120.  
  4121.     EXIT [WHEN condition]
  4122.  
  4123.   If the  optional WHEN part is present the exit of the loop will only take
  4124.   place if the condition is fulfilled. Otherwise the exit will take place uncon-
  4125.   ditionally.
  4126.  
  4127.     Example:
  4128.  
  4129.       OPEN 1,"SER:",READ        // Open serial port
  4130.       LOOP
  4131.         ch$=GET$(1,1)
  4132.         EXIT WHEN ch$=""26""    // ^Z (ASCII 26) is end of file
  4133.         PRINT ch$
  4134.       ENDLOOP
  4135.       CLOSE FILE 1
  4136.  
  4137.  
  4138.   3 Procedures and functions.
  4139.  
  4140.   One way  of designing  modular programs  in Comal  is by using procedures
  4141.   and functions.
  4142.  
  4143.   Procedures and functions are some sort of named  subprograms that  can be
  4144.   activated in any part of the program.
  4145.  
  4146.  
  4147.   3.1 Procedures.
  4148.  
  4149.   The general format of a procedure is
  4150.  
  4151.     PROC procedure_name[(formal_parameter_list)] [CLOSED]
  4152.       program_statements
  4153.     ENDPROC procedure_name
  4154.  
  4155.  
  4156.   The program_statements  inside the  procedure are activated by an execute
  4157.   statement. The format of this statement is
  4158.  
  4159.     procedure_name[(actual_parameter_list)]
  4160.  
  4161.  
  4162.                                          73
  4163.  
  4164.  
  4165.  
  4166.  
  4167.  
  4168.  
  4169.   The statements inside the procedure are executed as normal program state-
  4170.   ments. The  execution of  these statements  stops when the ENDPROC state-
  4171.   ment is reached or when a RETURN statement is executed.
  4172.  
  4173.   The format of a procedure RETURN statement is
  4174.  
  4175.     RETURN
  4176.  
  4177.  
  4178.   When the execution of the procedure statements stops,  the program execu-
  4179.   tion continues after the execute statement that activated the procedure.
  4180.  
  4181.   The name of a procedure is an identifier. Normally one chooses a name that
  4182.   reflects the action of the procedure. Procedures can be placed averywhere
  4183.   in the  program except  that it  may not  appear within IF, CASE, REPEAT,
  4184.   WHILE, FOR, LOOP and TRAP statements.
  4185.  
  4186.   It's a good idea to place procedures at the end of the program. In this way
  4187.   it reflects the top-down programming strategi.
  4188.  
  4189.  
  4190.   3.1.1 Procedures without parameters.
  4191.  
  4192.   The simplest form of procedures are the procedures without parameters. The
  4193.   general format of such procedures is
  4194.  
  4195.     PROC procedure_name
  4196.       program_statements
  4197.     ENDPROC procedure_name
  4198.  
  4199.   and they are activated by an execute statement of the form
  4200.  
  4201.     procedure_name
  4202.  
  4203.   Example: The procedure EraseToEndOfLine in this example will erase to the
  4204.     end of the line
  4205.  
  4206.         :
  4207.       REPEAT
  4208.         CURSOR 5,10
  4209.         EraseToEndOfLine
  4210.         INPUT "Enter number of disks (between 1 and 10): ": Num
  4211.       UNTIL Num>=1 AND Num<=10
  4212.         :
  4213.  
  4214.       PROC EraseToEndOfLine
  4215.         PRINT ""155"K",
  4216.       ENDPROC EraseToEndOfLine
  4217.  
  4218.  
  4219.                                          74
  4220.  
  4221.  
  4222.  
  4223.  
  4224.  
  4225.  
  4226.  
  4227.   3.1.2 Value parameters.
  4228.  
  4229.   Data can  be transferred  to procedures through parameters. There are two
  4230.   kinds of parameters: Value parameters and reference parameters. Value pa-
  4231.   rameters are exclusively used to transfer data into the procedure. Reference
  4232.   parameters are used both to transfere data into the procedure  and to get
  4233.   data back  from the  procedure. Value parameters and reference parameters
  4234.   can be mixed in procedures, but they are discussed in  separate sections.
  4235.   Reference parameters will be discussed in the next section.
  4236.  
  4237.   Value parameters are special kinds of local variables that are initialized
  4238.   when the procedure is called.
  4239.  
  4240.   A procedure with value parameters have the format
  4241.  
  4242.     PROC procedure_name(formal_parameter_list) [CLOSED]
  4243.       program_statements
  4244.     ENDPROC procedure_name
  4245.  
  4246.  
  4247.   The formal_parameter_list consists of one or more formal parameters sepa-
  4248.   rated by commas. The format of a formal value parameter is
  4249.  
  4250.     ParameterName [OF Type]
  4251.     IntegerName#
  4252.     StringName$
  4253.  
  4254.  
  4255.   If the type in the first form is not specified, the type of the parameter is
  4256.   set to FLOAT (the default type).
  4257.  
  4258.  
  4259.   Example: The procedure polygon in this  example draws  a polygon.  It re-
  4260.     quires that the Turtle module is loaded.
  4261.  
  4262.       PROC polygon(Corners OF UBYTE, SideLen OF FLOAT)
  4263.         LOOP Corners TIMES
  4264.           forward(SideLen)
  4265.           right(360/Corners)
  4266.         ENDLOOP
  4267.       ENDPROC polygon
  4268.  
  4269.  
  4270.   A procedure with parameter(s) is called by executing a line of the format
  4271.  
  4272.     procedure_name(actual_parameter_list)
  4273.  
  4274.  
  4275.  
  4276.                                          75
  4277.  
  4278.  
  4279.  
  4280.  
  4281.  
  4282.   The actual  parameters consists  of one  or more expressions separated by
  4283.   commas. The types of the expressions  must be  assignment compatible with
  4284.   the corresponding formal parameters, i.e. numbers must correspond to num-
  4285.   bers and strings to strings.
  4286.  
  4287.  
  4288.   Example:  The following procedure calls are all legal calls to the procedure
  4289.     polygon:
  4290.  
  4291.       DIM s OF BYTE
  4292.  
  4293.       polygon(3,s)
  4294.       polygon(4,3.5)
  4295.       polygon(6,25/3+s)
  4296.  
  4297.  
  4298.   A value  parameter can  be of  any type  except a  STRUC. An array can be
  4299.   transferred either by defining an array type and then use this type in the
  4300.   formal parameter description, or by using array indicators.
  4301.  
  4302.  
  4303.   Example:
  4304.  
  4305.     PROC ArrParProc1(Alfa OF ArrType)   // Array type used
  4306.     PROC ArrParProc2(Beta(,) OF LONG)   // Array indicator used
  4307.     TYPE ArrType=ARRAY(5,8) OF LONG
  4308.  
  4309.  
  4310.   In both  cases the  actual parameter must be an array name with array in-
  4311.   dicators.
  4312.  
  4313.  
  4314.   Example: The procedure PrintArray in this example prints an array as a two
  4315.     dimensional table.
  4316.  
  4317.     PROC PrintArray(Beta(,) OF BYTE)
  4318.       ZONE 5
  4319.       FOR i=1 to MAXINDEX(Beta(,),1) DO
  4320.         FOR j=1 TO MAXINDEX(Beta(,),2) DO
  4321.           PRINT Beta(i,j),
  4322.         ENDFOR j
  4323.         PRINT
  4324.       ENDFOR i
  4325.     ENDPROC PrintArray
  4326.  
  4327.     PrintArray(A(,))
  4328.  
  4329.  
  4330.   Note that  if arrays are used as value parameters, a copy of the array is
  4331.   made each time the procedure is called. This can result in a  lot of time
  4332.  
  4333.                                          76
  4334.  
  4335.  
  4336.  
  4337.  
  4338.  
  4339.   consuming copying. Therefor it is recommended to use reference parameters
  4340.   when possible (as for instance in the example above).
  4341.  
  4342.   Procedures (and functions) can be used as parameters. To do this a procu-
  4343.   dure (function) type has to be defined (see section 1.5).
  4344.  
  4345.  
  4346.   3.1.3 Reference parameters.
  4347.  
  4348.   Reference parameters can be used to return values back from a procedure.
  4349.  
  4350.   Procedures with reference parameters have the format
  4351.  
  4352.     PROC procedure_name(formal_parameter_list) [CLOSED]
  4353.       program_statements
  4354.     ENDPROC procedure_name
  4355.  
  4356.  
  4357.   The formal_parameter_list consists of one or more formal parameters sepa-
  4358.   rated by commas. The format of a formal referencee parameter is
  4359.  
  4360.     REF ParameterName [OF Type]
  4361.     REF IntegerName#
  4362.     REF StringName$
  4363.  
  4364.  
  4365.   If the type in the first form is not specified, the type of the parameter is
  4366.   set to FLOAT (the default type).
  4367.  
  4368.   Example: The  procedure swap  in this example interchanges the content of
  4369.     two string variables (with maximal length 50)
  4370.  
  4371.       text1$:="Text number 1"
  4372.       text2$:="Text number 2"
  4373.       swap(text1$,text2$)
  4374.  
  4375.       PROC swap(REF t1$,REF t2$)
  4376.         LOCAL Temp$ OF 50
  4377.  
  4378.         Temp$:=t1$
  4379.         t1$:=t2$
  4380.         t2$:=Temp$
  4381.       ENDPROC swap
  4382.  
  4383.  
  4384.   A procedure with reference parameter(s) is called by executing a line of the
  4385.   format
  4386.  
  4387.     procedure_name(actual_parameter_list)
  4388.  
  4389.  
  4390.                                          77
  4391.  
  4392.  
  4393.  
  4394.  
  4395.  
  4396.  
  4397.   The actual parameters consists of one or more variables separated by com-
  4398.   mas. The type of the variables must be the same as the type of the corre-
  4399.   sponding formal  parameters, i.e. string must correspond to string, FLOAT
  4400.   to FLOAT, ULONG to ULONG etc.
  4401.  
  4402.   At the call to a procedure with reference parameters a new local variable
  4403.   is not created (as was the case with value parameters). Only a new name is
  4404.   introduced to identify an existing variable. Every change made in the para-
  4405.   meter is therefore made on the variable used as the actual parameter in the
  4406.   calling line.
  4407.  
  4408.   To be specific. The changes made on the strings t1$ and t2$ in the proce-
  4409.   dure swap  in the  example above are in fact made on the string variables
  4410.   text1$ and text2$.
  4411.  
  4412.  
  4413.   3.1.4 Local procedures.
  4414.  
  4415.   It is possible to place procedures and/or functions inside a procedure (or
  4416.   function). Such a procedure is called a local procedure and it is only known
  4417.   inside the procedure where it is placed.
  4418.  
  4419.   Example:
  4420.  
  4421.     PROC QuickSort(REF t$(),Start OF LONG,End OF LONG)
  4422.       LOCAL temp$ OF 10, x$ OF 10
  4423.       LOCAL a OF LONG, z OF LONG
  4424.  
  4425.       a:=Start; z:=End; x$:=t$((Start+End)/2)
  4426.       REPEAT
  4427.         WHILE t$(a)<x$ DO a:+1
  4428.         WHILE x$<t$(z) DO z:-1
  4429.         IF a<=z THEN
  4430.           swap(t$(a),t$(z))
  4431.           a:+1; z:-1
  4432.         ENDIF
  4433.       UNTIL a>z
  4434.       IF Start<z THEN QuickSort(t$(),Start,z)
  4435.       IF a<End THEN QuickSort(t$(),a,End)
  4436.  
  4437.       PROC swap(REF t1$,REF t2$)
  4438.         LOCAL Temp$ OF 50
  4439.  
  4440.         Temp$:=t1$
  4441.         t1$:=t2$
  4442.         t2$:=Temp$
  4443.       ENDPROC swap
  4444.  
  4445.     ENDPROC QuickSort
  4446.  
  4447.                                          78
  4448.  
  4449.  
  4450.  
  4451.  
  4452.  
  4453.  
  4454.  
  4455.  
  4456.   3.1.5 Local and global variables. CLOSED procedures.
  4457.  
  4458.   Variables, procedures, functions and type definitions outside a procedure are
  4459.   accessible from a procedure.
  4460.  
  4461.   Further more, a variable created inside a procedure (either declared in a
  4462.   DIM statement or declared implicitely in an assignment statement) is in fact
  4463.   created out side the procedure an is still there after the procedure is left.
  4464.  
  4465.  
  4466.   Example: The output from the following little program
  4467.  
  4468.       x:=-5
  4469.       y:=-8
  4470.       MyProc
  4471.       PRINT x;y
  4472.  
  4473.       PROC MyProc
  4474.         x:=11
  4475.         y:=7
  4476.       ENDPROC MyProc
  4477.  
  4478.     is
  4479.  
  4480.       11 7
  4481.  
  4482.  
  4483.   Sometimes these effects of creating and/or using variables inside a proce-
  4484.   dure are intended. But in other cases it is the source of unpredictable and
  4485.   undiserable results.
  4486.  
  4487.   If a variable used inside a procedure is strictly local to that procedure, it
  4488.   should be declared as local. This is done in a LOCAL statement,  that has
  4489.   the same form as a DIM statement:
  4490.  
  4491.     LOCAL name[(dimension_specification)] [OF Type]
  4492.     LOCAL pntr_name OF POINTER TO Type
  4493.     LOCAL integer_name#[(dimension_specification)]
  4494.     LOCAL string_name$[(dimension_specification)] OF string_len
  4495.  
  4496.  
  4497.   Example: The output from the following little program
  4498.  
  4499.       x:=-5
  4500.       y:=-8
  4501.       MyProc
  4502.       PRINT x;y
  4503.  
  4504.                                          79
  4505.  
  4506.  
  4507.  
  4508.  
  4509.  
  4510.  
  4511.       PROC MyProc
  4512.         LOCAL x OF SHORT
  4513.         x:=11
  4514.         y:=7
  4515.       ENDPROC MyProc
  4516.  
  4517.     is
  4518.  
  4519.       -5 7
  4520.  
  4521.  
  4522.   Example:
  4523.  
  4524.     PROC QuickSort(REF t$(),Start OF LONG,End OF LONG)
  4525.       LOCAL temp$ OF 10, x$ OF 10
  4526.       LOCAL a OF LONG, z OF LONG
  4527.       a:=Start; z:=End; x$:=t$((Start+End)/2)
  4528.       REPEAT
  4529.         WHILE t$(a)<x$ DO a:+1
  4530.         WHILE x$<t$(z) DO z:-1
  4531.         IF a<=z THEN
  4532.           temp$:=t$(a); t$(a):=t$(z); t$(z):=temp$
  4533.           a:+1; z:-1
  4534.         ENDIF
  4535.       UNTIL a>z
  4536.       IF Start<z THEN QuickSort(t$(),Start,z)
  4537.       IF a<End THEN QuickSort(t$(),a,End)
  4538.     ENDPROC QuickSort
  4539.  
  4540.  
  4541.   The use of local variables prevents undiserable name coincidence. Another
  4542.   way to avoid this is to make the procedure closed. This is accomplished by
  4543.   adding the word CLOSED at the end of the PROC line.
  4544.  
  4545.   All variables in a closed procedure are local, and variables, procedures and
  4546.   functions found outside the procedure is unknown inside the procedure.
  4547.  
  4548.   Example: The output from the following little program is -5 -8
  4549.  
  4550.  
  4551.       x:=-5
  4552.       y:=-8
  4553.       MyProc
  4554.       PRINT x;y
  4555.  
  4556.       PROC MyProc CLOSED
  4557.         x:=11
  4558.         y:=7
  4559.       ENDPROC MyProc
  4560.  
  4561.                                          80
  4562.  
  4563.  
  4564.  
  4565.  
  4566.  
  4567.  
  4568.  
  4569.   In order to make identifiers outside a closed procedure accessible it is pos-
  4570.   sible to  import them. This is done by using the IPMPORT statement or the
  4571.   GLOBAL statement.
  4572.  
  4573.   The IMPORT statement is used to import identifiers from the program level
  4574.   just below  the procedures  level (for  instance another procedure if the
  4575.   IMPORT statement is placed  in a  local procedure).  The GLOBAL statement
  4576.   imports identifiers from the main part of the current program environment
  4577.   (from the main program, from the initialization part of a  module or from
  4578.   the fields in a STRUC if the GLOBAL statement is placed in a method).
  4579.  
  4580.   The general format of an IMPORT statement and a GLOBAL statement is
  4581.  
  4582.     IMPORT name_list
  4583.     GLOBAL name_list
  4584.  
  4585.   where name_list is one or more names separated by commas.
  4586.  
  4587.   Example:
  4588.     IMPORT a,Beta,Str$
  4589.     GLOBAL p#,Alfa$,x
  4590.  
  4591.  
  4592.   Example:  The QuickSort procedure could have been written (although it is
  4593.     not recommendable):
  4594.  
  4595.     PROC QuickSort(Start OF LONG,End OF LONG) CLOSED
  4596.       IMPORT t$
  4597.       DIM temp$ OF 10, x$ OF 10
  4598.       DIM a OF LONG, z OF LONG
  4599.       a:=Start; z:=End; x$:=t$((Start+End)/2)
  4600.       REPEAT
  4601.         WHILE t$(a)<x$ DO a:+1
  4602.         WHILE x$<t$(z) DO z:-1
  4603.         IF a<=z THEN
  4604.           temp$:=t$(a); t$(a):=t$(z); t$(z):=temp$
  4605.           a:+1; z:-1
  4606.         ENDIF
  4607.       UNTIL a>z
  4608.       IF Start<z THEN QuickSort(Start,z)
  4609.       IF a<End THEN QuickSort(a,End)
  4610.     ENDPROC QuickSort
  4611.  
  4612.  
  4613.   It is possible to place USE statements and TYPE definition statements in-
  4614.   side a closed procedure.
  4615.  
  4616.  
  4617.  
  4618.                                          81
  4619.  
  4620.  
  4621.  
  4622.  
  4623.  
  4624.   3.2 Functions.
  4625.  
  4626.   The FUNC  statement is  used to  define funtions. The general format of a
  4627.   FUNC statement is
  4628.  
  4629.     FUNC func_name[(formal_parameter_list)] [OF NumType] [CLOSED]
  4630.       program_statements
  4631.     ENDFUNC func_name
  4632.  
  4633.   or
  4634.  
  4635.     FUNC int_func_name#[(formal_parameter_list)] [CLOSED]
  4636.       program_statements
  4637.     ENDFUNC int_func_name#
  4638.  
  4639.   or
  4640.  
  4641.     FUNC str_func_name$[(formal_parameter_list)] [CLOSED]
  4642.       program_statements
  4643.     ENDFUNC str_func_name$
  4644.  
  4645.  
  4646.   The default type in the first form is FLOAT. The value returned by a func-
  4647.   tion is calculated in a function RETURN statement of the form:
  4648.  
  4649.     RETURN expression
  4650.  
  4651.  
  4652.   The expression  must match with the function type and there have to be at
  4653.   least one function RETURN line in a function.
  4654.  
  4655.   The program statements inside the functions are activated  by placing the
  4656.   function name in an expression.
  4657.  
  4658.   Examples:
  4659.  
  4660.     PRINT 1-errf(1.5)
  4661.     y:=sinh(x)/cosh(x)
  4662.  
  4663.  
  4664.   Except for the returned value, there is no difference between functions and
  4665.   procedures. The sections 3.1.1 to 3.1.5 holds for functions, too.
  4666.  
  4667.   Example: The following function gcd calculates the greatest common divisor
  4668.     of two integer numbers
  4669.  
  4670.       FUNC gcd(m OF LONG,n OF LONG)
  4671.         IF (m MOD n)=0 THEN
  4672.           RETURN n
  4673.         ELSE
  4674.  
  4675.                                          82
  4676.  
  4677.  
  4678.  
  4679.  
  4680.  
  4681.           RETURN gcd(n,m MOD n)
  4682.         ENDIF
  4683.       ENDFUNC gcd
  4684.  
  4685.  
  4686.   Example: The following function WaitKey$ waits for special keys to be en-
  4687.     tered
  4688.  
  4689.         :
  4690.       PRINT "Yes or No (Y/N)? ",
  4691.       IF WaitKey$("YyNn") IN "Yy" THEN
  4692.         :
  4693.       ELSE
  4694.         :
  4695.       ENDIF
  4696.         :
  4697.  
  4698.       FUNC WaitKey$(WaitChars$)
  4699.         LOCAL ch$ OF 1
  4700.         REPEAT
  4701.           ch$:=INKEY$
  4702.         UNTIL ch$ IN WaitChars$
  4703.         PRINT ch$,
  4704.         RETURN ch$
  4705.       ENDFUNC WaitKey$
  4706.  
  4707.  
  4708.   Example: The following function  PenColor$ returns  a string  that can be
  4709.     used to set the drawing color of the console
  4710.  
  4711.         :
  4712.       PRINT PenColor$(3),"A nice color",PenColor$(1)
  4713.         :
  4714.  
  4715.       FUNC PenColor$(col OF UBYTE)
  4716.         RETURN CHR$($9B)+STR$(30+(col MOD 7))+"m"
  4717.       ENDFUNC PenColor$
  4718.  
  4719.  
  4720.   4 Exception handling.
  4721.  
  4722.   This section describes how exceptions such as user break and run time er-
  4723.   rors may be handled.
  4724.  
  4725.   4.1 The TRAP statement.
  4726.  
  4727.   Normally a run time error such as Division by zero or Out  of memory will
  4728.   result in  a program  stop. This  can be prevented by the TRAP statement.
  4729.   The format of a TRAP statement is
  4730.  
  4731.  
  4732.                                          83
  4733.  
  4734.  
  4735.  
  4736.  
  4737.  
  4738.       TRAP
  4739.         statements_1
  4740.       HANDLER
  4741.         statements_2
  4742.       ENDTRAP
  4743.  
  4744.  
  4745.   If an error is detected during the execution af statements_1 then the seg-
  4746.   ment statements_2  will be executed. Otherwise the program continues with
  4747.   the first statement after ENDTRAP.
  4748.  
  4749.  
  4750.   Example: In this example two files are used. If an error is detected during
  4751.     the opening of the second file the first one has to be closed before the
  4752.     the program stops
  4753.  
  4754.       OPEN FILE 1,File1$,WRITE
  4755.       TRAP
  4756.         OPEN FILE 2,File2$,READ
  4757.       HANDLER
  4758.         CLOSE FILE 1
  4759.         REPORT
  4760.       ENDTRAP
  4761.  
  4762.         :
  4763.  
  4764.  
  4765.  
  4766.   In connection with the handling of errors a number of error handling state-
  4767.   ments an convenient system functions are available:
  4768.  
  4769.       REPORT [ErrNum,[ErrText$]]
  4770.  
  4771.         This statement can be used to generate an error.
  4772.  
  4773.         If used  alone the error reported will be the error that caused the
  4774.         HANDLER section to be executed.
  4775.  
  4776.         If ErrNum is present the error text connected to this number will be
  4777.         reported.
  4778.  
  4779.         If ErrText$ is present this test will be reported.
  4780.  
  4781.  
  4782.       RETRY
  4783.  
  4784.         This statement directs the execution back to the first statement in
  4785.         statemens_1.
  4786.  
  4787.  
  4788.  
  4789.                                          84
  4790.  
  4791.  
  4792.  
  4793.  
  4794.  
  4795.       ERR
  4796.  
  4797.         A function that returns the error number of the error detected.
  4798.  
  4799.  
  4800.       ERRFILE
  4801.  
  4802.         A function that returns the number of the  file in  question if the
  4803.         error occurs in connection with a file operation.
  4804.  
  4805.  
  4806.       ERRTEXT$
  4807.  
  4808.         A function that returns the string containing the error message that
  4809.         the system would have generated.
  4810.  
  4811.  
  4812.   Example:  This piece of code reads  a  number  using  the  standard input
  4813.     statement INPUT. If the input is not a legal number the screen is flashed
  4814.     and the input statement is reexecuted:
  4815.  
  4816.         TRAP
  4817.           INPUT AT 5,10: "Enter a number: ": Num
  4818.         HANDLER
  4819.           PRINT CHR$(7),
  4820.           RETRY
  4821.         ENDTRAP
  4822.  
  4823.  
  4824.  
  4825.   4.2 The TRAP ESC statement.
  4826.  
  4827.   If the user presses the Esc-key (while the execute window  is active) the
  4828.   program will normally be breaked.
  4829.  
  4830.   The TRAP  ESC statement  is used  to control the operation of user breaks
  4831.   from within a Comal program.
  4832.  
  4833.   By executing TRAP ESC+ a user  break will  be handled  in the  normal way
  4834.   (the execution is interrupted).
  4835.  
  4836.   By executing TRAP ESC- the following will occur:
  4837.  
  4838.     - Ppressing the Esc-key will no longer interrupt a running program.
  4839.  
  4840.     - The system  function ESC  equals FALSE  (=0) until  the user tries to
  4841.       break the program; then it equals TRUE (=1).
  4842.  
  4843.   Thus a Comal program can use the value of ESC to check for user break.
  4844.  
  4845.  
  4846.                                          85
  4847.  
  4848.  
  4849.  
  4850.  
  4851.  
  4852.   Note, that the selection of the Stop Execution  item in  the Program menu
  4853.   cannot be masked, i.e. the program will always be stopped by doing this.
  4854.  
  4855.  
  4856.  
  4857.   5 IO statements.
  4858.  
  4859.   In this section the different forms of IO statements will be described. The
  4860.   most frequent used IO statements are PRINt and INPUT.
  4861.  
  4862.  
  4863.   5.1 The PRINT statement.
  4864.  
  4865.   The general format of the output statement PRINT is
  4866.  
  4867.     PRINT [AT Row,Col:] [USING Format_text:] [print_list] [mark]
  4868.  
  4869.    
  4870.   Simple PRINT statement
  4871.  
  4872.     The simplest for af the PRINT statement has the form
  4873.  
  4874.       PRINT print_list [mark]
  4875.  
  4876.     where print_list is one ore more of the following separated by either a
  4877.     comma (,) or a semicolon (;)
  4878.  
  4879.       TAB(position)
  4880.  
  4881.         where position is a numeric expression with value from 1 to 255
  4882.  
  4883.       string expression
  4884.  
  4885.       number expression
  4886.  
  4887.     and mark is either a comma (,) or a semicolon (;).
  4888.  
  4889.     The use  of TAB will result in the output of spaces up to the specified
  4890.     position if this position is not already passed.
  4891.  
  4892.     The separator comma (,) has no influence on the output (it acts solely as
  4893.     a separator). The separator semicolon (;) outputs spaces up to the next
  4894.     ZONE tabulation (the default ZONE tabulation is one resulting always in
  4895.     the output one extra space).
  4896.  
  4897.     If mark is not used a terminating line feed is output. If present it acts
  4898.     like the separator.
  4899.  
  4900.  
  4901.  
  4902.  
  4903.                                          86
  4904.  
  4905.  
  4906.  
  4907.  
  4908.  
  4909.     Examples:
  4910.  
  4911.       PRINT 2;-3
  4912.       PRINT "x=",x;"y=",y
  4913.       PRINT x,TAB(8),
  4914.       PRINT y,TAB(16)
  4915.       PRINT SIN(x);
  4916.       PRINT             // Output an empty line
  4917.  
  4918.  
  4919.   Formatted output with PRINT USING
  4920.  
  4921.     The PRINT USING statement allows formatted  output. This  statement has
  4922.     the format:
  4923.  
  4924.       PRINT USING Format_text: [print_list] [mark]
  4925.  
  4926.     where Format_text is a normal text expression containing the format cha-
  4927.     racters '#' '.' and '-' and print_list is one ore more number expressions
  4928.     separated by comma (,).
  4929.  
  4930.     Examples:
  4931.  
  4932.       PRINT USING "Pi = #.####": PI
  4933.       FOR x=0 TO 2*PI STEP 0.2 DO
  4934.         PRINT USING "sin(#.#)=-#.####":x,SIN(x)
  4935.       ENDFOR x
  4936.  
  4937.     All the characters in the the format except the special formmat charac-
  4938.     ters are printed as is. The format fields in the text are replaced one by
  4939.     one by  the values of the number expressions in the Print_list. To make
  4940.     room for a sign a minus sign (-) has to precede the format characters.
  4941.  
  4942.  
  4943.   PRINT AT specified position in window
  4944.  
  4945.     The beginning of the output can be set to any position of the screen by
  4946.     means of the PRINT AT statement with the form
  4947.  
  4948.       PRINT AT Row,Col: [USING Format_text:] [print_list] [mark]
  4949.  
  4950.  
  4951.     Examples:
  4952.  
  4953.       PRINT AT 10,20: "Hello world!"
  4954.       PRINT AT 0,20: USING "Pi = #.####": PI
  4955.  
  4956.  
  4957.     If Row is zero the current line is used, and if Col is zero the current
  4958.     column is used.
  4959.  
  4960.                                          87
  4961.  
  4962.  
  4963.  
  4964.  
  4965.  
  4966.  
  4967.  
  4968.   5.2 The INPUT statement.
  4969.  
  4970.   The general format of the input statement INPUT is
  4971.  
  4972.     INPUT [AT Row,Col[,lenght]:] [Promt-string:] variable_list [mark]
  4973.  
  4974.  
  4975.   Simple INPUT statement
  4976.  
  4977.     The simple form of the INPUT statement is
  4978.  
  4979.       INPUT [Promt_string:] variable_list [mark]
  4980.  
  4981.     where variable_list is one ore more text or number variables separated by
  4982.     comma (,) and mark has the same effect as in the PRINT statement.
  4983.  
  4984.  
  4985.     Example:
  4986.  
  4987.       INPUT x,y,t$
  4988.       INPUT "Enter a text: ": t$
  4989.  
  4990.  
  4991.     If the Promt_string is present this will be printed. Otherwise a question
  4992.     mark (?) wil be printed. Then the cursor is turned on and  the user may
  4993.     type in the values for the variables. The input is terminated by pressing
  4994.     the <ENTER>  key. The  values entered  are assigned  one by  one to the
  4995.     variables in the variable list. A string variable will be assigned the rest
  4996.     of the line entered.
  4997.  
  4998.  
  4999.   INPUT AT specified position in window
  5000.  
  5001.     The beginning of the promt string can be set to any position of the win-
  5002.     dow by means of the INPUT AT statement with the form
  5003.  
  5004.       INPUT AT Row,Col: [Promt-string:] variable_list [mark]
  5005.  
  5006.  
  5007.     Example:
  5008.  
  5009.       INPUT AT 5,10: "Enter a number: ": Num
  5010.  
  5011.  
  5012.     If Row is zero the current line is used, and if Col is zero the current
  5013.     column is used (like PRINT AT).
  5014.  
  5015.  
  5016.  
  5017.                                          88
  5018.  
  5019.  
  5020.  
  5021.  
  5022.  
  5023.   Specifying the length of the input field
  5024.  
  5025.     By adding a lengthfield to the  AT part  of an  INPUT AT  statement the
  5026.     length of  the input field can be specified. The general format of this
  5027.     statement is
  5028.  
  5029.       INPUT AT Row,Col,Lenght: [Promt-string:] variable_list [mark]
  5030.  
  5031.  
  5032.     Example:
  5033.  
  5034.       INPUT AT 0,0,1: "Accept (Y/N)? ": Answer$
  5035.  
  5036.  
  5037.   5.3 Redirection of IO.
  5038.  
  5039.   Normally all IO goes through the console attached to the program. But it is
  5040.   possible to redirect input and/or output to another device or a file. This
  5041.   done by using the SELECT statement that has the form:
  5042.  
  5043.     SELECT Direction File$
  5044.  
  5045.   where Direction is INPUT, OUTPUT or  INOUT and  File$ is  either the name
  5046.   of a file or the name of one of the standard devices
  5047.  
  5048.     ds:   the console window (only output)
  5049.     kb:   the keyboard (only input)
  5050.     lp:   a printer (only output)
  5051.  
  5052.  
  5053.     Example:
  5054.  
  5055.       INPUT "Output on printer (Y/N)? ": Answer$
  5056.  
  5057.       IF "Yy" IN Answer$ THEN
  5058.         SELECT OUTPUT "lp:"     // Select printer
  5059.         MakeOutput
  5060.         SELECT OUTPUT "ds:"     // Output back to window
  5061.       ELSE
  5062.         MakeOutput
  5063.       ENDIF
  5064.  
  5065.  
  5066.   It is  possible to  add other devices than the three above (or replace an
  5067.   existing one). To do this you have to write device drivers for that device
  5068.   and then add the device to the device list. Normally these drivers is writ-
  5069.   ten in C, but it is possible to write them in Comal, too. See chapter VII.
  5070.  
  5071.  
  5072.  
  5073.  
  5074.                                          89
  5075.  
  5076.  
  5077.  
  5078.  
  5079.  
  5080.   5.4 System functions performing IO.
  5081.  
  5082.   A number of system function can be used to perform IO. These are
  5083.  
  5084.  
  5085.     FUNC KEY$
  5086.  
  5087.       By calling this string function the keyboard buffer is scanned. If there
  5088.       is no  key in  the buffer the empty string is returned. Otherwise the
  5089.       first key in the buffer is returned. Note that some  keys return more
  5090.       than a single character.
  5091.  
  5092.       The key returned (if any) is not echoed on the window.
  5093.  
  5094.       Example:
  5095.  
  5096.         PRINT "Press any key to continue"
  5097.         WHILE KEY$="" DO WAIT
  5098.  
  5099.  
  5100.     FUNC INKEY$
  5101.  
  5102.       This string  function does the same as KEY$ but if there is no key in
  5103.       the buffer the empty string is not returned. In stead the process will
  5104.       go to sleep until a key is pressed.
  5105.  
  5106.       The key returned is not echoed on the window.
  5107.  
  5108.  
  5109.     FUNC INKEY$(time_out)
  5110.  
  5111.       This string function does the same as INKEY$ but if there is no key in
  5112.       the buffer it will wait maximal time_out seconds for a keypress before
  5113.       continuing program  execution. If  no keypress is detected within the
  5114.       time limit the empty strin is returned.
  5115.  
  5116.       The key returned (if any) is not echoed on the window.
  5117.  
  5118.  
  5119.   5.5 Other IO related statements and functions.
  5120.  
  5121.  
  5122.     CURSOR Row,Col
  5123.  
  5124.       Statement used to place the cursor on the window.
  5125.  
  5126.       If Row is zero the current line is used, and if Col is zero the current
  5127.       column is used (like PRINT AT and INPUT AT).
  5128.  
  5129.  
  5130.  
  5131.                                          90
  5132.  
  5133.  
  5134.  
  5135.  
  5136.  
  5137.       Example:
  5138.  
  5139.         CURSOR 15,5
  5140.  
  5141.  
  5142.  
  5143.     CURCOL
  5144.  
  5145.       Function returning the current column position of the cursor.
  5146.  
  5147.       Example:
  5148.  
  5149.         CurX:=CURCOL
  5150.  
  5151.  
  5152.  
  5153.     CURROW
  5154.  
  5155.       Function returning the current row position of the cursor.
  5156.  
  5157.       Example:
  5158.  
  5159.         CurY:=CURROW
  5160.  
  5161.  
  5162.  
  5163.     PAGE
  5164.  
  5165.       Statement used to clear the screen or make a form feed (page eject) if
  5166.       the current output direction is the printer.
  5167.  
  5168.       Example:
  5169.  
  5170.         PAGE
  5171.  
  5172.  
  5173.     ZONE tab_interval
  5174.  
  5175.       Statement used to set the width of the  tab zone  on the  window (see
  5176.       description of the separator semicolon (;) in section 5.1)
  5177.  
  5178.       Example:
  5179.  
  5180.         ZONE 8
  5181.  
  5182.       At startup the zone value is 1.
  5183.  
  5184.  
  5185.  
  5186.  
  5187.  
  5188.                                          91
  5189.  
  5190.  
  5191.  
  5192.  
  5193.  
  5194.     ZONE
  5195.  
  5196.       Function used to return the current zone value.
  5197.  
  5198.       Example:
  5199.  
  5200.         OldZone:=ZONE
  5201.  
  5202.  
  5203.  
  5204.     DIGITS number_of_digits
  5205.  
  5206.       Statement used to specify the number of significant digits wich will be
  5207.       shown in any PRINT statement.
  5208.  
  5209.       Example:
  5210.  
  5211.         DIGITS 12
  5212.  
  5213.       At startup the number of digits is 10.
  5214.  
  5215.  
  5216.     DIGITS
  5217.  
  5218.       Function used to return the current  number of  digits used  in PRINT
  5219.       statements.
  5220.  
  5221.       Example:
  5222.  
  5223.         OldDigits:=DIGITS
  5224.  
  5225.  
  5226.  
  5227.  
  5228.   6 File statements.
  5229.  
  5230.  
  5231.   Comal saves  data on  external starage media using two different types of
  5232.   data files:
  5233.  
  5234.     - Sequential files
  5235.  
  5236.     - Random access files (direct files)
  5237.  
  5238.   Further more data can be saved in two different formats:
  5239.  
  5240.     - Binary format
  5241.  
  5242.     - ASCII format (text files)
  5243.  
  5244.  
  5245.                                          92
  5246.  
  5247.  
  5248.  
  5249.  
  5250.  
  5251.  
  5252.   6.1 Sequential binary files.
  5253.  
  5254.   In a sequential file one item is saved after another without regard for the
  5255.   space that each item occupies.
  5256.  
  5257.   A sequential  data file  has to  be opened before you can read from it or
  5258.   write to it. This is done by executing an OPEN statement of the format
  5259.  
  5260.     OPEN FILE FileNo,FileName$,OpenMode
  5261.  
  5262.   where FileNo is a number in the range 1..32767 used to identify  the file
  5263.   and OpenMode is one of the following:
  5264.  
  5265.     READ        file is opened for reading only
  5266.     WRITE       write only (create new file or overwrite existing file)
  5267.     READWRITE   both read and write access possible
  5268.     APPEND      write access (append to existing or create a new file)
  5269.  
  5270.  
  5271.   FileName$ is  the name  of an  AmigaDOS file  or the  name of  one of the
  5272.   standard devices introduced in section 5.3.  Normally the  READWRITE open
  5273.   mode is used only in connection with special devices such as a serial devi-
  5274.   ce.
  5275.  
  5276.  
  5277.   Example:
  5278.  
  5279.     OPEN FILE 2,"MyFile",APPEND
  5280.     OPEN FILE 1,"Data",READ
  5281.  
  5282.  
  5283.   Data is written to a sequential binary file using a WRITE statement of the
  5284.   form:
  5285.  
  5286.     WRITE FILE FileNo: write_list
  5287.  
  5288.   where write_list is one or more expressions or variables separated by com-
  5289.   mas (,) and FileNo is the number used in the OPEN statement.
  5290.  
  5291.  
  5292.   Example:
  5293.  
  5294.     WRITE FILE 1: Alfa,Text$,Beta
  5295.     WRITE FILE 9: 2+4,3.14159,"Amiga"+"DOS"
  5296.  
  5297.  
  5298.   It is possible to write a whole record or a whole array to a  file in one
  5299.   write statement.
  5300.  
  5301.  
  5302.                                          93
  5303.  
  5304.  
  5305.  
  5306.  
  5307.  
  5308.  
  5309.   Example:
  5310.     DIM Member OF Person
  5311.     DIM Club(100) OF Person
  5312.  
  5313.       :
  5314.  
  5315.     WRITE FILE 2: Member
  5316.     WRITE FILE 2: Club()      // Note the array indicator
  5317.  
  5318.  
  5319.   Data is  read from a sequential binary file using a READ statement of the
  5320.   form:
  5321.  
  5322.     READ FILE FileNo: read_list
  5323.  
  5324.   where read_list is one or more variables separated by commas (,) and File-
  5325.   No is the number used in the OPEN statement.
  5326.  
  5327.  
  5328.   Example:
  5329.     READ FILE 1: Alfa,Text$,Beta
  5330.     READ FILE 9: n,x,t$
  5331.     READ FILE 2: Member,Club()
  5332.  
  5333.  
  5334.   The type  of the variables used to read in data from a file must have the
  5335.   same type as the corresponding data written to the file. It is very impor-
  5336.   tant that you observe this rule. Comal has almost no way to test the type
  5337.   of the data saved on a file.
  5338.  
  5339.   It is recommended that you always use variables (and not  expressions) in
  5340.   the  WRITE  statements.  Then  you  can pair WRITE and READ statements by
  5341.   using the same variables:
  5342.  
  5343.     WRITE FILE 1: Alfa,Text$,Beta
  5344.  
  5345.       :
  5346.  
  5347.     READ FILE 1: Alfa,Text$,Beta
  5348.  
  5349.  
  5350.   When file operations have been completed the file must be closed by using
  5351.   a CLOSE statement of the form:
  5352.  
  5353.     CLOSE [FILE FileNo]
  5354.  
  5355.  
  5356.   If FileNo is specified only this file will be closed. Otherwise all currently
  5357.   opened files will be closed.
  5358.  
  5359.                                          94
  5360.  
  5361.  
  5362.  
  5363.  
  5364.  
  5365.  
  5366.   Example:
  5367.  
  5368.     CLOSE FILE 2
  5369.     CLOSE
  5370.  
  5371.  
  5372.   Example: This little program will print out the whole content of a file con-
  5373.     taining short integer numbers:
  5374.  
  5375.       DIM n OF SHORT
  5376.  
  5377.       OPEN FILE 1,"Numbers",READ
  5378.       WHILE NOT EOF(1) DO
  5379.         READ FILE 1: n
  5380.         PRINT n
  5381.       ENDWHILE
  5382.       CLOSE FILE 1
  5383.  
  5384.  
  5385.     The function EOF used in the program is discussed in section 6.4.
  5386.  
  5387.  
  5388.   6.2 Random access binary files.
  5389.  
  5390.   In a random access file data items is stored on fixed positions in the file.
  5391.   A random access file is some times refered to as a direct file, because a
  5392.   specific number of bytes is reserved for each record (a group of data items)
  5393.   allowing direct access to a record when its number is known.
  5394.  
  5395.   A random access file must exist before you can open it (in contradiction to
  5396.   sequential files opened in WRITE or APPEND mode). A random access file is
  5397.   created by using a CREATE statement:
  5398.  
  5399.     CREATE FileName$,NoOfRecords,RecordLength
  5400.  
  5401.  
  5402.   where FileName$ is the name of the file you are going to create and NoOf-
  5403.   Records is the total number of records each one having the length Record-
  5404.   Length.
  5405.  
  5406.   The statement creates a file containing NoOfRecords records numbered from
  5407.   1 to NoOfRecords). The file is filled with CHR$(0).
  5408.  
  5409.  
  5410.   Example:
  5411.  
  5412.     CREATE "Numbers",100,12   // 100 records each holding one long integer
  5413.                               // .. and one float
  5414.     CREATE "Addresses",50,27  // 50 records each holding a text of max. 25
  5415.  
  5416.                                          95
  5417.  
  5418.  
  5419.  
  5420.  
  5421.  
  5422.  
  5423.  
  5424.   When you  are going  to create  a data  file you  have to decide how many
  5425.   records you need and to caclulate the necessary  size of  the records. To
  5426.   make this  calculation you  have to  use this  information about how many
  5427.   bytes each data item occupies in the record:
  5428.  
  5429.     - a text item occupies the actual length of the text (returned by the LEN
  5430.       function) plus two. The last two bytes is used to hold the actual length
  5431.       of the text.
  5432.  
  5433.     - all other data items occupies the size returned by the function SIZE.
  5434.  
  5435.  
  5436.   For the simple data types the SIZE function will return:
  5437.  
  5438.     UBYTE and BYTE:   1
  5439.     USHORT and SHORT: 2
  5440.     ULONG and LONG:   4
  5441.     FLOAT:            8
  5442.  
  5443.  
  5444.   Example: To create a file that is to hold 200 records each holding the con-
  5445.     tent of the structure
  5446.  
  5447.         STRUC Person
  5448.           DIM Name$ OF 30
  5449.           DIM Address$ OF 30
  5450.           DIM City$ OF 20
  5451.           DIM Age of UBYTE
  5452.         ENDSTRUC Person
  5453.  
  5454.     you could do the following:
  5455.  
  5456.         DIM Person of Person
  5457.         CREATE "PersonFile",200,SIZE(Person)
  5458.  
  5459.  
  5460.  
  5461.   A random  access binary  file is opened by executing an OPEN statement of
  5462.   the form
  5463.  
  5464.     OPEN FILE FileNo,FileName$,RANDOM RecordLength
  5465.  
  5466.  
  5467.   where FileNo and FileName$ is the  same as  discussed in  connection with
  5468.   sequential files and RecordLength is the size of the records in the file (the
  5469.   same size as was used to create the file).
  5470.  
  5471.  
  5472.  
  5473.                                          96
  5474.  
  5475.  
  5476.  
  5477.  
  5478.  
  5479.   Example:
  5480.     OPEN FILE 1,"Numbers",RANDOM 4
  5481.     OPEN FILE 2,"Addresses",RANDOM 27
  5482.     OPEN FILE 3,"PersonFile",RANDOM SIZE(Person)
  5483.  
  5484.  
  5485.   Data is written to a random access binary file using a WRITE statement of
  5486.   the form:
  5487.  
  5488.     WRITE FILE FileNo,RecordNo[,Offset]: write_list
  5489.  
  5490.   where FileNo  and write_list  is the same as discussed in connection with
  5491.   sequential files and RecordNo is the number of the record (a positive inte-
  5492.   ger) you want to update.
  5493.  
  5494.   If Offset is present the writing starts Offset bytes from the start of the
  5495.   record (default is zero). The Offset option is rarely used.
  5496.  
  5497.   Examples:
  5498.     WRITE FILE 1,51: n,x
  5499.     WRITE FILE 2,1: Address$
  5500.  
  5501.   Data is read from a random access binary file using  a READ  statement of
  5502.   the form:
  5503.  
  5504.     READ FILE FileNo,RecordNo[,Offset]: read_list
  5505.  
  5506.   where FileNo and read_list is the same as discussed in connection with se-
  5507.   quential files and RecordNo is the number of the record (a positive integer)
  5508.   you want to read.
  5509.  
  5510.   If Offset is present the reading starts Offset bytes from the start of the
  5511.   record (default is zero). The Offset option is rarely used.
  5512.  
  5513.   Examples:
  5514.  
  5515.     READ FILE 1,51: n,x
  5516.     READ FILE 2,1: Address$
  5517.  
  5518.  
  5519.   When file operations have been completed the file must be closed by using
  5520.   a CLOSE statement of the same form as discussed in the preceding section.
  5521.  
  5522.  
  5523.  
  5524.   6.3 ASCII files.
  5525.  
  5526.   ASCII files (text files) are always sequential. An ASCII file is opened in the
  5527.   same way as a sequential binary file, e.i. executing a statement of the form:
  5528.  
  5529.  
  5530.                                          97
  5531.  
  5532.  
  5533.  
  5534.  
  5535.  
  5536.     OPEN FILE FileNo,FileName$,OpenMode
  5537.  
  5538.   where FileNo is a number in the range 1..32767 used to identify  the file
  5539.   and OpenMode is one of the following:
  5540.  
  5541.     READ        file is opened for reading only
  5542.     WRITE       write only (create new file or overwrite existing file)
  5543.     READWRITE   both read and write access possible
  5544.     APPEND      write access (append to existing or create a new file)
  5545.  
  5546.  
  5547.   FileName$ is  the name  of an  AmigaDOS file  or the  name of  one of the
  5548.   standard devices introduced in section 5.3.  Normally the  READWRITE open
  5549.   mode is used only in connection with special devices such as a serial devi-
  5550.   ce.
  5551.  
  5552.  
  5553.   Example:
  5554.  
  5555.     OPEN FILE 2,"MyFile",APPEND
  5556.     OPEN FILE 1,"Data",READ
  5557.     OPEN FILE 7,"SER:",READWRITE    // "SER:" is the AmigaDOS serial device
  5558.     OPEN FILE 5,"lp:",WRITE         // "lp:" is the printer device
  5559.  
  5560.  
  5561.   Data is written to an ASCII file using a PRINT statement of the form:
  5562.  
  5563.     PRINT FILE FileNo: [USING Format_text:] [print_list] [mark]
  5564.  
  5565.   where FileNo is the number used in the  OPEN statement.  The rest  of the
  5566.   statement has the same form as a PRINT statement discussed in section 5.1.
  5567.  
  5568.  
  5569.   Example:
  5570.  
  5571.     PRINT FILE 1: Alfa,Text$
  5572.     PRINT FILE 5: USING "n = #### x = ##.####": n,x
  5573.  
  5574.  
  5575.   Data is written from an ASCII file using an INPUT statement of the form:
  5576.  
  5577.     INPUT FILE FileNo: variable_list [mark]
  5578.  
  5579.   where FileNo  is the  number used  in the OPEN statement. The rest of the
  5580.   statement has the same  form as  a INPUT  statement discussed  in section
  5581.   5.2.
  5582.  
  5583.  
  5584.  
  5585.  
  5586.  
  5587.                                          98
  5588.  
  5589.  
  5590.  
  5591.  
  5592.  
  5593.   Example:
  5594.  
  5595.     INPUT FILE 1: Alfa,Text$
  5596.     INPUT FILE 5: n,x
  5597.  
  5598.  
  5599.   When file operations have been completed the file must be closed by using
  5600.   a CLOSE statement of the same form as discussed in the preceding sections.
  5601.  
  5602.  
  5603.   Example: This little program will print out the whole content of a text file:
  5604.  
  5605.       DIM Line$ OF 150
  5606.  
  5607.       OPEN FILE 1,"Text",READ
  5608.       WHILE NOT EOF(1) DO
  5609.         INPUT FILE 1: Line$
  5610.         PRINT Line$
  5611.       ENDWHILE
  5612.       CLOSE FILE 1
  5613.  
  5614.     The function EOF used in the program is discussed in next section.
  5615.  
  5616.  
  5617.  
  5618.   6.4 File system related functions.
  5619.  
  5620.   A number of system functions are used in connection with files. These are
  5621.  
  5622.  
  5623.       EOF(FileNo)
  5624.  
  5625.         This function returns TRUE if the internal file pointer of the file
  5626.         opened with file number FileNo is positioned at the end of the file
  5627.         (EOF = End Of File). Otherwise it returns FALSE
  5628.  
  5629.         EOF returns TRUE as soon as the last  data item  are read  from the
  5630.         file. If an empty file is opened a call to EOF will return TRUE be-
  5631.         fore any reading at all.
  5632.  
  5633.         The following code fraction shows a safe way to read the whole con-
  5634.         tent of a (possibly empty) file
  5635.  
  5636.             OPEN FILE 1,"Name",READ
  5637.             WHILE NOT EOF(1) DO
  5638.                 :
  5639.               <do your reading>
  5640.                 :
  5641.             ENDWHILE
  5642.             CLOSE FILE 1
  5643.  
  5644.                                          99
  5645.  
  5646.  
  5647.  
  5648.  
  5649.  
  5650.  
  5651.  
  5652.       FREEFILE
  5653.  
  5654.         Returns the next available file number. This function is useful in li-
  5655.         brary procedures/functions which are to be used in various programs.
  5656.  
  5657.         Example:
  5658.  
  5659.           DIM FileNo OF SHORT
  5660.  
  5661.           FileNo:=FREEFILE
  5662.           OPEN FILE FileNo,FileName$,APPEND
  5663.             :
  5664.  
  5665.  
  5666.       GET$(FileNo,NumberOfCharaters)
  5667.  
  5668.         This string function fetches NumberOfCharaters characters  from the
  5669.         file opened with file number FileNo. The length of the string retur-
  5670.         ned will be NumberOfCharaters unless the end of file is reached first.
  5671.         In this case the string will only be those characters retrieved prior
  5672.         to the end of file.
  5673.  
  5674.         Example: This little program can be used to make a copy of any file
  5675.           (even a binary file which is not a Comal file)
  5676.  
  5677.             DIM Block$ OF 1000
  5678.  
  5679.             OPEN FILE 1,Source$,READ
  5680.             OPEN FILE 2,Destination$,WRITE
  5681.             WHILE NOT EOF(1)
  5682.               Block$=GET$(1,1000)
  5683.               PRINT FILE 2: Block$,
  5684.             ENDWHILE
  5685.             CLOSE
  5686.  
  5687.           Note the comma at the end of the PRINT FILE statement!
  5688.  
  5689.  
  5690.   6.5 READ and DATA statements.
  5691.  
  5692.   The READ  statement is  used to  read internal data stored in one or more
  5693.   data statements.
  5694.  
  5695.   The format of the READ statement is:
  5696.  
  5697.     READ read_list
  5698.  
  5699.   where read_list is one or more variables separated by commas (,).
  5700.  
  5701.                                          100
  5702.  
  5703.  
  5704.  
  5705.  
  5706.  
  5707.  
  5708.   When a READ statemet is executed the variables in the  READ statement are
  5709.   assigned values from the internal data queue formed by DATA statements in
  5710.   the program.
  5711.  
  5712.   The format of a DATA statement is:
  5713.  
  5714.     DATA data_list
  5715.  
  5716.   where data_list is one ore more number or string expressions separated by
  5717.   commas (,).
  5718.  
  5719.  
  5720.   Example: After  the execution of the DATA statement in the following pro-
  5721.     gram fraction the variable a will have the value 5, b the value 7, c the
  5722.     value 3 and t$ the value "A string" (without the quotes).
  5723.  
  5724.       READ a,t$,b,c
  5725.  
  5726.         :
  5727.  
  5728.       DATA 5
  5729.       DATA "A string",7,3
  5730.  
  5731.  
  5732.   It is possible to fill a whole array in one read.
  5733.  
  5734.  
  5735.   Example: The following two program fractions are equivalent
  5736.  
  5737.       DIM a(3,4)
  5738.  
  5739.       FOR i:=1 TO 3 DO
  5740.         FOR j:=1 TO 4 DO
  5741.           READ a(,)
  5742.         ENDFOR j
  5743.       ENDFOR i
  5744.  
  5745.         :
  5746.         :
  5747.  
  5748.       DATA 1,2,3,4
  5749.       DATA 5,6,7,8
  5750.       DATA 9,10,11,12
  5751.  
  5752.     and
  5753.  
  5754.       DIM a(3,4)
  5755.  
  5756.       READ a(,)
  5757.  
  5758.                                          101
  5759.  
  5760.  
  5761.  
  5762.  
  5763.  
  5764.  
  5765.         :
  5766.         :
  5767.  
  5768.       DATA 1,2,3,4
  5769.       DATA 5,6,7,8
  5770.       DATA 9,10,11,12
  5771.  
  5772.  
  5773.   The values are read one by one in the order the DATA constants are placed
  5774.   in the program. It is possible to change  this order  by using  a RESTORE
  5775.   statement of the form:
  5776.  
  5777.       RESTORE label
  5778.  
  5779.   where label is a label is defined in a label line (see section 2.3.1).
  5780.  
  5781.  
  5782.   Example:
  5783.  
  5784.       READ a,b
  5785.       RESTORE d
  5786.       READ c
  5787.  
  5788.       DATA 1
  5789.       d:
  5790.       DATA 2
  5791.  
  5792.  
  5793.   If you  are trying to read beyond the last data constant in the queue the
  5794.   program will stop with an error message. It is possible to test for the end
  5795.   of the  data queue  by using the function EOD (End Of Data). The function
  5796.   returns true (1) if there is no more data in the queue. Otherwise it returns
  5797.   false (0).
  5798.  
  5799.   The READ  and DATA statements are useful to initialize arrays or structu-
  5800.   res.
  5801.  
  5802.  
  5803.   Example: The  NewWindow structure  used to  open an  Intuition window can
  5804.     be initialized in this way:
  5805.  
  5806.       DIM NewWindow OF NewWindow
  5807.  
  5808.       READ NewWindow
  5809.  
  5810.         :
  5811.  
  5812.       DATA 10,20,400,100,-1,-1  // Potition, size and pen colors
  5813.       DATA 0                    // No IDCMP flags
  5814.  
  5815.                                          102
  5816.  
  5817.  
  5818.  
  5819.  
  5820.  
  5821.       DATA WINDOWSIZING BITOR WINDOWDEPTH BITOR WINDOWDRAG
  5822.       DATA 0,0                  // Gadget and image
  5823.       DATA ADR("My window")     // Window title
  5824.       DATA 0,0                  // Screen and bitmap
  5825.       DATA 100,40,640,200       // Max and min size
  5826.       DATA WBENCHSCREEN         // Type
  5827.  
  5828.         :
  5829.  
  5830.  
  5831.  
  5832.   7 Miscellaneous statements, procedures and functions.
  5833.   
  5834.  
  5835.   7.1 DOS statements and functions.
  5836.  
  5837.   A number  of statements  can be  used to execute AmigaDOS commands. These
  5838.   statements are:
  5839.  
  5840.     CAT
  5841.  
  5842.       CAT is synonymous for DIR. CAT is relisted as DIR.
  5843.  
  5844.  
  5845.     CD
  5846.  
  5847.       CD is synonymous for CHDIR. CD is relisted as CHDIR.
  5848.  
  5849.  
  5850.     CHDIR
  5851.  
  5852.       Change the current directory. The format of the statement is:
  5853.  
  5854.         CHDIR path
  5855.  
  5856.       where path is a string expression.
  5857.  
  5858.       The statement works as the shell command CHDIR.
  5859.  
  5860.       Example:
  5861.  
  5862.         CHDIR "Demos"
  5863.         CHDIR "/"
  5864.         CHDIR Path$+"/Example"
  5865.  
  5866.     COPY
  5867.  
  5868.       Make a copy of a file. The format of the statement is:
  5869.  
  5870.         COPY OldFile,NewFile
  5871.  
  5872.                                          103
  5873.  
  5874.  
  5875.  
  5876.  
  5877.  
  5878.  
  5879.       where OldFile and NewFile are string expressions.
  5880.  
  5881.       The statement works as  the shell  command COPY  except that  the new
  5882.       name must be specified.
  5883.  
  5884.       Example:
  5885.  
  5886.         COPY "Demos/Hanoi","Ram:Hanoi"
  5887.  
  5888.  
  5889.     DELETE
  5890.  
  5891.       Remove a file from disk. The format of the statement is:
  5892.  
  5893.         DELETE FileName
  5894.  
  5895.       where FileName is a string expression.
  5896.  
  5897.       Example:
  5898.  
  5899.         DELETE "ram:Temp"
  5900.  
  5901.  
  5902.     DIR
  5903.  
  5904.       Output a  directory list  of a volume or directory. The format of the
  5905.       statement is
  5906.  
  5907.         DIR path
  5908.  
  5909.       where path is a string expression.
  5910.  
  5911.       The statement works as the shell command DIR.
  5912.  
  5913.       Example:
  5914.         DIR                 // The current directory is listed
  5915.         DIR "Modules"       // The directory Modules is listed
  5916.         DIR "df0:"+Drawer$
  5917.         DIR DIR$            // Same as just DIR
  5918.  
  5919.  
  5920.     DIR$
  5921.  
  5922.       String function returning the complete path of the current directory.
  5923.       The path string will always end with a colon (:) or a slash (/).
  5924.  
  5925.       Example:
  5926.         PRINT DIR$
  5927.         Path$:=DIR$
  5928.  
  5929.                                          104
  5930.  
  5931.  
  5932.  
  5933.  
  5934.  
  5935.  
  5936.  
  5937.     MAKEDIR
  5938.  
  5939.       Synonymous for MKDIR. MAKEDIR is relisted as MKDIR.
  5940.  
  5941.  
  5942.     MKDIR
  5943.  
  5944.       Statement used  to create  a new subdirectory (drawer). The format of
  5945.       the statement is
  5946.  
  5947.         MKDIR name
  5948.  
  5949.       where name is a string expression.
  5950.  
  5951.       The statement works as the shell command MAKEDIR.
  5952.  
  5953.       Example:
  5954.  
  5955.         MKDIR "Comal:AsciiFiles"
  5956.  
  5957.  
  5958.     PASS
  5959.  
  5960.       Statement used to execute shell commands directly. The format is
  5961.  
  5962.         PASS command
  5963.  
  5964.       where command is a string expression.  As a  result of  executing the
  5965.       command a  window will  open in  the Workbench screen and the command
  5966.       will be executed with this window as the output window. After the exe-
  5967.       cution of  the command  you will  be requested to press enter to con-
  5968.       tinue.
  5969.  
  5970.       If the  command string  commadn is  the empty  string a  new Shell is
  5971.       opened. Type  ENDCLI (or  press the close gadget in WB 2.x) to return
  5972.       to your Comal program.
  5973.  
  5974.       Example:
  5975.  
  5976.         PASS "RELABEL df0: NewName"
  5977.         PASS ""
  5978.  
  5979.  
  5980.     RENAME
  5981.  
  5982.       Statement used to give  a disk  file a  new name.  The format  of the
  5983.       statement is:
  5984.  
  5985.  
  5986.                                          105
  5987.  
  5988.  
  5989.  
  5990.  
  5991.  
  5992.         COPY OldName,NewName
  5993.  
  5994.       where OldName and NewName are string expressions.
  5995.  
  5996.       The statement works as the shell command RENAME.
  5997.  
  5998.       Example:
  5999.  
  6000.         RENAME "Demos/Hanoi","Demos/Towers"
  6001.  
  6002.  
  6003.     UNIT
  6004.  
  6005.       Synonymous for CHDIR. UNIT is relisted as CHDIR.
  6006.  
  6007.  
  6008.     UNIT$
  6009.  
  6010.       String function  returning the name of the volume containing the cur-
  6011.       rent directory.
  6012.  
  6013.       Example:
  6014.  
  6015.         PRINT UNIT$
  6016.         Volume$:=UNIT$
  6017.  
  6018.  
  6019.   7.2 Time related statements and functions.
  6020.  
  6021.  
  6022.     DATE$
  6023.  
  6024.       String function returning the current date. The string returned has the
  6025.       format yyyy-mm-dd.
  6026.  
  6027.  
  6028.     TIME$
  6029.  
  6030.       String function returning the current time. The string returned has the
  6031.       format hh:mm:ss.
  6032.  
  6033.  
  6034.     TIMER
  6035.  
  6036.       Statement used to set the value of an internal constant running timer.
  6037.  
  6038.       Example:
  6039.  
  6040.         TIMER 0         // Reset the timer
  6041.  
  6042.  
  6043.                                          106
  6044.  
  6045.  
  6046.  
  6047.  
  6048.  
  6049.  
  6050.     TIMER
  6051.  
  6052.       Number function used the return the current value of the internal ti-
  6053.       mer.
  6054.  
  6055.       Example:
  6056.  
  6057.         PRINT TIMER
  6058.  
  6059.  
  6060.     WAIT
  6061.  
  6062.       Statement used  to make  your process sleep. The format of the state-
  6063.       ment is:
  6064.  
  6065.         WAIT [delaylength]
  6066.  
  6067.       where delaylength is a number expression.
  6068.  
  6069.       If delaylength is specified the process will sleep for the specified num-
  6070.       ber of seconds. If no delaylength is specified the process will sleep
  6071.       until an event occurs (for instance a key is pressed).
  6072.  
  6073.       Example:
  6074.  
  6075.         WAIT 5                    // Sleep in 5 seconds
  6076.         WHILE KEY$="" DO WAIT
  6077.  
  6078.  
  6079.  
  6080.   7.3 Random numbers.
  6081.  
  6082.   The function RND is used to generate pseudo  random numbers.  The are two
  6083.   forms of the function RND:
  6084.  
  6085.     RND
  6086.  
  6087.       Used without  arguments the  function RND  returns a (pseudo) randaom
  6088.       number in the interval [0;1[ (1 not included).
  6089.  
  6090.  
  6091.     RND(min,max)
  6092.  
  6093.       Used with arguments an  integer random  number greater  than or equal
  6094.       min and less than or equal max is returned.
  6095.  
  6096.  
  6097.   The random  numbers are read from a random number table (the table values
  6098.   are calculated one by one). To make Comal start a new place in this table
  6099.  
  6100.                                          107
  6101.  
  6102.  
  6103.  
  6104.  
  6105.  
  6106.   the  RANDOMIZE  statement  may  be  used.  The  format  of  the RANDOMIZE
  6107.   statement is
  6108.  
  6109.     RANDOMIZE [seed]
  6110.  
  6111.  
  6112.   If seed (a numeric expression) is not present the Amiga timer is  used to
  6113.   generate the seed.
  6114.  
  6115.  
  6116.   Example: The  following program  will return  the same  random number se-
  6117.     quence each time it is run:
  6118.  
  6119.       RANDOMIZE 100
  6120.  
  6121.       LOOP 10 TIMES
  6122.         PRINT RND
  6123.       ENDLOOP
  6124.  
  6125.  
  6126.  
  6127.   7.4 STOP and END statements.
  6128.  
  6129.   A Comal program will stop after the last statement of the program  is ex-
  6130.   ecuted. To  make the  program stop before the last statement the STOP and
  6131.   END statements may be used. The format of these statements is:
  6132.  
  6133.     STOP [message]
  6134.     END [message]
  6135.  
  6136.   where message is a string expression whose value is printed in the status
  6137.   line of the editor.
  6138.  
  6139.   The  most  importent  difference  between  the STOP and END statements is
  6140.   that the program execution cannot be continued after execution of the END
  6141.   statements.
  6142.  
  6143.   If the STOP statement is executed the cursor of the editor is placed after
  6144.   the STOP and the  message STOP  statement is  executed is  printed in the
  6145.   status line (unless message is present).
  6146.  
  6147.  
  6148.   Example:
  6149.  
  6150.     STOP "Error while opening the file"
  6151.     END
  6152.  
  6153.  
  6154.  
  6155.  
  6156.  
  6157.                                          108
  6158.  
  6159.  
  6160.  
  6161.  
  6162.  
  6163.   7.5 Interrupt procedures.
  6164.  
  6165.   It is possible to make interrupt procedures in Comal. An interrupt procedure
  6166.   is a procedure with the format:
  6167.  
  6168.     PROC Interrupt(SigMask OF ULONG) CLOSED
  6169.  
  6170.  
  6171.   To activate the interrupt procedure a call must be made to the Comal pro-
  6172.   cedure ADDINTERRUPT:
  6173.  
  6174.     ADDINTERRUPT(Interrupt(),SigMask)
  6175.  
  6176.   or
  6177.  
  6178.     ADDINTERRUPT(Interrupt(),SigMask,Priority)
  6179.  
  6180.  
  6181.   where the  parameter SigMask is a mask containing the signals that should
  6182.   cause interrupt (more about signals in the Amiga system manual). Interrupt
  6183.   are prioritized. In the second version the parameter Priority the priority
  6184.   sets this priority (-128 .. 127). The default priority used in the first version
  6185.   is 0.
  6186.  
  6187.   To deactivate  the interrupt  procedure a  call must be made to the Comal
  6188.   procedure REMINTERRUPT:
  6189.  
  6190.     REMINTERRUPT(Interrupt())
  6191.  
  6192.  
  6193.  
  6194.   7.6 Mathematical functions.
  6195.  
  6196.  
  6197.     ABS         absolute value
  6198.  
  6199.       ABS(x) returns the absolute value (numerical value) of the argument x
  6200.       which may be any real number.
  6201.  
  6202.  
  6203.     ACS         arccosine
  6204.  
  6205.       ACS(x) returns  the arccosine in radians of the argument x which is a
  6206.       real number in the range from -1 to 1.
  6207.  
  6208.  
  6209.     ASN         arcsine
  6210.  
  6211.       ASN(x) returns the arcsine in radians of the  argument x   is  a real
  6212.       number in the range from -1 to 1.
  6213.  
  6214.                                          109
  6215.  
  6216.  
  6217.  
  6218.  
  6219.  
  6220.  
  6221.     ATN         arctangent
  6222.  
  6223.       ATN(x) returns  the arccosine  in radians of the argument x which may
  6224.       be any real number.
  6225.  
  6226.  
  6227.     COS         cosine
  6228.  
  6229.       COS(x) returns the cosine of the argument x measured in radians.
  6230.  
  6231.  
  6232.     EXP(x)      natural exponential function
  6233.  
  6234.       EXP(x) returns the number e (=2.718281828..) raised to the power of the
  6235.       argument x.
  6236.  
  6237.  
  6238.     FLOAT
  6239.  
  6240.       FLOAT(i) returns a floating point number equalto the argument i which
  6241.       is normally an integer (but may be any number).
  6242.  
  6243.  
  6244.     INT
  6245.  
  6246.       INT(x) returns the largest integer integer which is less than or equal
  6247.       to the argument x.
  6248.  
  6249.  
  6250.     LOG         natural logarithm
  6251.  
  6252.       LOG(x) returns the natural logarithm of the argument x which is a po-
  6253.       sitive real number.
  6254.  
  6255.  
  6256.     PI
  6257.  
  6258.       PI is a constant function returning the number pi (=3.1415592655...).
  6259.  
  6260.  
  6261.     ROUND
  6262.  
  6263.       ROUND(x) returns the integer which is closest to the argument x.
  6264.  
  6265.  
  6266.     SGN         sign
  6267.  
  6268.       SGN(x) returns -1 if the argument x is negative, 0 if it is zero and +1
  6269.       if x is positive.
  6270.  
  6271.                                          110
  6272.  
  6273.  
  6274.  
  6275.  
  6276.  
  6277.  
  6278.  
  6279.     SIN         sine
  6280.  
  6281.       SIN(x) returns the sine of the argument x measured in radians.
  6282.  
  6283.  
  6284.     SQR         square root
  6285.  
  6286.       SQR(x) returns the square root of a non negative argument x.
  6287.  
  6288.  
  6289.     TAN         tangent
  6290.  
  6291.       TAN(x) returns the tangent of the argument x measured in radians.
  6292.  
  6293.  
  6294.  
  6295.   7.7 Functions involving strings.
  6296.  
  6297.  
  6298.     CHR$
  6299.  
  6300.       CHR$(x) returns a string containing the character with ASCII value x.
  6301.  
  6302.  
  6303.     LEN         string length
  6304.  
  6305.       LEN(t$) returns the length (number of character) of the string expres-
  6306.       sion used as argument.
  6307.  
  6308.  
  6309.     ORD         ordinal value
  6310.  
  6311.       ORD(t$) returns an integer representing the ASCII value  of the first
  6312.       character of the string expression used as argument. An error will re-
  6313.       sult if the empty string is used as argument.
  6314.  
  6315.  
  6316.     SPC$
  6317.  
  6318.       SPC$(n) returns the number of blanks (spaces) specified  by the argu-
  6319.       ment n.
  6320.  
  6321.  
  6322.     STR$
  6323.  
  6324.       STR$(num) returns  the string equivalent of the numeric argument num.
  6325.       The number of significant digits are set by the DIGITS statement.
  6326.  
  6327.  
  6328.                                          111
  6329.  
  6330.  
  6331.  
  6332.  
  6333.  
  6334.       STR$(format$,num) returns  the string  equivalent of  the numeric ar-
  6335.       gument num.  The string  argument format$ specifies the format of the
  6336.       string equivalent. See description of PRINT USING in  section 5.1 for
  6337.       further details.
  6338.  
  6339.       Example: The output from
  6340.  
  6341.           PRINT STR$("#.###",pi)
  6342.  
  6343.         will be
  6344.  
  6345.           3.142
  6346.  
  6347.  
  6348.     VAL
  6349.  
  6350.       VAL(t$) returns the numeric equivalent of a string representing a num-
  6351.       ber. VAL and STR$ can be concidered as inverse of each other.
  6352.  
  6353.  
  6354.  
  6355.   7.8 Other functions.
  6356.  
  6357.  
  6358.     ADR
  6359.  
  6360.       Function returning the address of the data field of a variable, the code
  6361.       of a procedure/function or the address of the text in a text constant.
  6362.  
  6363.       Example:
  6364.  
  6365.         ADR(NewWindow)
  6366.         ADR("My window")
  6367.  
  6368.     FREE
  6369.  
  6370.       FREE returns the number of free bytes in the work space.
  6371.  
  6372.  
  6373.     SIZE
  6374.  
  6375.       SIZE(var) returns the number of bytes occupied byt the variable var.
  6376.  
  6377.  
  6378.  
  6379.  
  6380.  
  6381.  
  6382.  
  6383.  
  6384.  
  6385.                                          112
  6386.  
  6387.  
  6388.  
  6389.  
  6390.  
  6391.   8 Objects.
  6392.  
  6393.   Very often  a computer  program can  be viewed  of as a model of the real
  6394.   world. In these cases a very powerful program design strategi is to base the
  6395.   structures of the program on the structures of the part of the world being
  6396.   modeled. For each object in the real world we should  try to  construct a
  6397.   corresponding computational object. Such a design strategi is called Object
  6398.   Oriented Programming design strategi (or short OOP).
  6399.  
  6400.   OOP is still rather unknown and section 8.1 is an introduction to this pro-
  6401.   gramming strategi. The sections 8.2-8.4 contains a more formal description
  6402.   of objects.
  6403.  
  6404.  
  6405.   8.1 Introduction to OOP.
  6406.  
  6407.   As an example to OOP we are going to make  a simple  model of  a bank ac-
  6408.   count. A  bank account is identified by a number (an ID code), there is a
  6409.   balance and an interest. All together these quantities are characterizing a
  6410.   specific bank account and it would be natural to put them into a structure:
  6411.  
  6412.     STRUC BankAccount
  6413.       Id OF ULONG
  6414.       Balance OF FLOAT
  6415.       Interrest OF FLOAT
  6416.     ENDSTRUC BankAccount
  6417.  
  6418.  
  6419.   Operations can be made on a bank account. In our simple model this is de-
  6420.   positing and withdrawal of money which can be implemented by  a procedure
  6421.   and a function:
  6422.  
  6423.  
  6424.     PROC Deposit(REF Account OF BankAccount,Amount)
  6425.       Account.Balance:+Amount
  6426.     ENDPROC Deposit
  6427.  
  6428.     FUNC Withdraw(REF Account OF BankAccount,Amount) OF SHORT
  6429.       IF Account.Balance-Amount>=0 THEN
  6430.         Account.Balance:-Amount
  6431.         RETURN TRUE
  6432.       ELSE
  6433.         RETURN FALSE
  6434.       ENDIF
  6435.     UNDFUNC Withdraw
  6436.  
  6437.  
  6438.   The function  Withdraw returns  true if  there is enough money on the ac-
  6439.   count to accomodate the withdrawal. Otherwise it returns false.
  6440.  
  6441.  
  6442.                                          113
  6443.  
  6444.  
  6445.  
  6446.  
  6447.  
  6448.   With these definitions bank accounts  can  be  created  by  executing DIM
  6449.   statements:
  6450.  
  6451.     DIM MyAccount OF BankAccount
  6452.     DIM YourAccount OF BankAccount
  6453.  
  6454.   and operations can be made through the procedure Deposit and the function
  6455.   Withdraw:
  6456.  
  6457.     Deposit(MyAccount,1000)
  6458.  
  6459.     IF Withdraw(YourAccount,1750) THEN
  6460.       PRINT "New balance: ",YourAccount.Balance
  6461.     ELSE
  6462.       PRINT "Insufficient founds"
  6463.       PRINT "Balance is: ",YourAccount.Balance
  6464.     ENDIF
  6465.  
  6466.  
  6467.   The operations Deposit and  Withdraw are  closely bound  to the structure
  6468.   BankAccount and it would be natural to put them into the structure defini-
  6469.   tion itself. This is in fact possible and can be done by defining BankAc-
  6470.   count like:
  6471.  
  6472.     STRUC BankAccount
  6473.       Id OF ULONG
  6474.       Balance OF FLOAT
  6475.       Interrest OF FLOAT
  6476.  
  6477.       PROC Deposit(Amount)
  6478.         Balance:+Amount
  6479.       ENDPROC Deposit
  6480.  
  6481.       FUNC Withdraw(Amount) OF SHORT
  6482.         IF Balance-Amount>=0 THEN
  6483.           Balance:-Amount
  6484.           RETURN TRUE
  6485.         ELSE
  6486.           RETURN FALSE
  6487.         ENDIF
  6488.       UNDFUNC Withdraw
  6489.  
  6490.     ENDSTRUC BankAccount
  6491.  
  6492.  
  6493.  
  6494.   Procedures and  functions defined inside a structure are sometimes called
  6495.   methods. Methods cannot be closed but are otherwise normal procedures and
  6496.   functions.
  6497.  
  6498.  
  6499.                                          114
  6500.  
  6501.  
  6502.  
  6503.  
  6504.  
  6505.   With this new definition bank accounts are still created by executing DIM
  6506.   statements:
  6507.  
  6508.     DIM MyAccount OF BankAccount
  6509.     DIM YourAccount OF BankAccount
  6510.  
  6511.   and operations can be made through the metods using the dot notation:
  6512.  
  6513.     MyAccount.Deposit(1000)
  6514.  
  6515.     IF YourAccount.Withdraw(1750) THEN
  6516.       PRINT "New balance: ",YourAccount.Balance
  6517.     ELSE
  6518.       PRINT "Insufficient founds"
  6519.       PRINT "Balance is: ",YourAccount.Balance
  6520.     ENDIF
  6521.  
  6522.  
  6523.   By using methods everything that has to do with the  bank account  is put
  6524.   into the structure definition. This is callded encapsulation and is one of the
  6525.   central elements in OOP. Another important element is the use  of the in-
  6526.   heritance mechanism to conveniently derive new types from existing types.
  6527.  
  6528.   A cash credit is a bank account where the balance is allowed to be negati-
  6529.   ve (until some predefined negative value). Apart from this it shares all the
  6530.   proporties of a normal bank account. In making a model of a cash credit it
  6531.   would be natural to try to  reuse BankAccount.  This may  be done  in the
  6532.   following way where BankAccount is inherited:
  6533.  
  6534.     STRUC CashCredit
  6535.       INHERIT BankAccount
  6536.  
  6537.       DIM MinBalance OF FLOAT
  6538.  
  6539.       FUNC Withdraw(Amount) OF SHORT
  6540.         IF Balance-Amount>=0 THEN
  6541.           Balance:-Amount
  6542.           RETURN TRUE
  6543.         ELSE
  6544.           RETURN FALSE
  6545.         ENDIF
  6546.       UNDFUNC Withdraw
  6547.  
  6548.     ENDSTRUC CashCredit
  6549.  
  6550.  
  6551.  
  6552.   This new definition of the bank account type can be used like the old one
  6553.   and at the same time:
  6554.  
  6555.  
  6556.                                          115
  6557.  
  6558.  
  6559.  
  6560.  
  6561.  
  6562.     DIM MyAccount OF BankAccount
  6563.     DIM YourAccount OF BankAccount
  6564.     DIM Cash OF CashCredit
  6565.  
  6566.     MyAccount.Deposit(1000)
  6567.     Cash.Deposit(2000)
  6568.  
  6569.     IF Cash.Withdraw(1750) THEN
  6570.       PRINT "New balance: ",Cash.Balance
  6571.     ELSE
  6572.       PRINT "Insufficient founds or illegal password"
  6573.       PRINT "Balance is: ",Cash.Balance
  6574.     ENDIF
  6575.  
  6576.  
  6577.   Note that the new function Withdraw in CashCredit  overloads the original
  6578.   Withdraw function  in BankAccount. All other fields or methods of BankAc-
  6579.   count are inherited and can be used as if they were defined inside the new
  6580.   type CashCredit.
  6581.  
  6582.   There is another way to reuse BankAccount in the new CashCredit. First we
  6583.   have to redefine the structure BankAccount:
  6584.  
  6585.     STRUC BankAccount
  6586.       Id OF ULONG
  6587.       Balance OF FLOAT
  6588.       Interrest OF FLOAT
  6589.  
  6590.       PROC Deposit(Amount)
  6591.         Balance:+Amount
  6592.       ENDPROC Deposit
  6593.  
  6594.       FUNC Withdraw(Amount) OF SHORT
  6595.         Balance:-Amount
  6596.         IF Proceed THEN
  6597.           RETURN TRUE
  6598.         ELSE
  6599.           Balance:+Amount
  6600.           RETURN FALSE
  6601.         ENDIF
  6602.       UNDFUNC Withdraw
  6603.  
  6604.       FUNC Proceed OF SHORT VIRTUAL
  6605.         RETURN Balance>=0
  6606.       ENDFUNC Proceed
  6607.  
  6608.     ENDSTRUC BankAccount
  6609.  
  6610.  
  6611.  
  6612.  
  6613.                                          116
  6614.  
  6615.  
  6616.  
  6617.  
  6618.  
  6619.   The legitimacy of the withdraw transaction is tested by the function Pro-
  6620.   ceed which is declared as VIRTUAL. The meaning of this will be clear soon.
  6621.   Note that allthough BankAccount has been redefined all the code  that has
  6622.   used BankAccount until now need not be rewritten.
  6623.  
  6624.   Now the CashCredit structure can be defined in this way:
  6625.  
  6626.     STRUC CashCredit
  6627.       INHERIT BankAccount
  6628.  
  6629.       DIM MinBalance OF FLOAT
  6630.  
  6631.       FUNC Proceed OF SHORT
  6632.         RETURN Balance>=MinBalance
  6633.       ENDFUNC Proceed
  6634.  
  6635.     ENDSTRUC CashCredit
  6636.  
  6637.  
  6638.   To se  how this  works let  us make  one normal bank account and one cash
  6639.   credit by executing the statements:
  6640.  
  6641.     DIM Account OF BankAccount
  6642.     DIM Cash OF CashCredit
  6643.  
  6644.  
  6645.   If the statement
  6646.  
  6647.     IF Cash.Withdraw(750) THEN
  6648.  
  6649.   is executed the method Withdraw of  the structure  BankAccount is called.
  6650.   Inside this method another method Proceed is activated. But since Proceed
  6651.   in BankAccount is declared as VIRTUAL it is not this one that is called. In
  6652.   stead the method Proceed defined in CashCredit is called and this version
  6653.   of Proceed compares Balance with MinBalance in stead of comparing it with
  6654.   zero.
  6655.  
  6656.   On the other hand, if the statement
  6657.  
  6658.     IF Account.Withdraw(750) THEN
  6659.  
  6660.   is executed the method Withdraw of the structure Account is again called.
  6661.   But this time the object BankAccount has no descendants and it is the ori-
  6662.   ginal method Proceed inside BankAccount that is activated.
  6663.  
  6664.   As a final example let us define a special password-protected bank account
  6665.   where a password has  to be  supplied to  withdraw money.  This new pass-
  6666.   word-protected bank  account shares all the properties of the simple bank
  6667.   account. These properties are inherited from BankAccount in the following
  6668.   definition of ProtectAccount:
  6669.  
  6670.                                          117
  6671.  
  6672.  
  6673.  
  6674.  
  6675.  
  6676.  
  6677.     STRUC ProtectAccount
  6678.       INHERIT BankAccount
  6679.  
  6680.       DIM Password$ OF 10
  6681.  
  6682.       FUNC Proceed OF SHORT
  6683.         LOCAL pw$ OF 10
  6684.  
  6685.         INPUT "Enter password: ":pw$
  6686.         IF pw$=Password$ THEN
  6687.           RETURN BankAccount.Proceed
  6688.         ELSE
  6689.           PRINT "Illegal password"
  6690.           RETURN FALSE
  6691.         ENDIF
  6692.       UNDFUNC Proceed
  6693.  
  6694.     ENDSTRUC BankAccount
  6695.  
  6696.  
  6697.  
  6698.   8.2 Methods.
  6699.  
  6700.   An object type is a STRUC type (discussed in section 1.3.2) extended with
  6701.   one or more procedures or functions. The general format of an object type
  6702.   definition is
  6703.  
  6704.     STRUC Identifier
  6705.  
  6706.       [USE statements]
  6707.  
  6708.       DeclarationStatements
  6709.  
  6710.     ENDSTRUC Identifier
  6711.  
  6712.   where DeclarationStatements is one or more of the following
  6713.  
  6714.     - structure DIM statement (see section 1.3.2)
  6715.  
  6716.     - open procedure
  6717.  
  6718.     - open function
  6719.  
  6720.  
  6721.  
  6722.   Procedures and  functions in  an object  type are called methods. Methods
  6723.   must be open but are otherwise normal procedures or functions.
  6724.  
  6725.  
  6726.  
  6727.                                          118
  6728.  
  6729.  
  6730.  
  6731.  
  6732.  
  6733.   Example:
  6734.  
  6735.     STRUC Person
  6736.       DIM FirstName$ OF 20
  6737.       DIM LastName$ OF 20
  6738.       DIM Address$ OF 30
  6739.       DIM City$ OF 20
  6740.       DIM Age of UBYTE
  6741.  
  6742.       PROC Input
  6743.         INPUT "First name: ": FirstName$
  6744.         INPUT "Last name:  ": LastName$
  6745.         INPUT "Address:    ": Address$
  6746.         INPUT "City:       ": City$
  6747.         INPUT "Age:        ": Age
  6748.       ENDPROC Input
  6749.  
  6750.       PROC Print
  6751.         PRINT "First name: ", FirstName$
  6752.         PRINT "Last name:  ", LastName$
  6753.         PRINT "Address:    ", Address$
  6754.         PRINT "City:       ", City$
  6755.         PRINT "Age:        ", Age
  6756.       ENDPROC Print
  6757.  
  6758.     ENDSTRUC Person
  6759.  
  6760.  
  6761.   A object variable or a pointer  to an  object must  dimensioned in  a DIM
  6762.   statement as normal data structures discussed in section 1.3.
  6763.  
  6764.  
  6765.   Example:
  6766.  
  6767.     DIM Member OF Person
  6768.     DIM Club(100) OF Person
  6769.     DIM PersonPtr OF POINTER TO Person
  6770.  
  6771.     ALLOCATE(PersonPtr)
  6772.  
  6773.  
  6774.   Methods are activated by using the dot notation on the variable.
  6775.  
  6776.  
  6777.   Example:
  6778.  
  6779.     FOR i:=1 TO 100
  6780.       Club(i).Print
  6781.     ENDFOR i
  6782.     PersonPtr@.Input
  6783.  
  6784.                                          119
  6785.  
  6786.  
  6787.  
  6788.  
  6789.  
  6790.  
  6791.  
  6792.   The scope of a method is the fields and the other methods inside the actual
  6793.   object.
  6794.  
  6795.  
  6796.   Example: The scope of Club(23).Print is the method  Input and  the fields
  6797.     FrstName$, LastName$, Address$, City$ and Age of Club(23).
  6798.  
  6799.  
  6800.   An object  type is  a true  extension of the data structure STRUC so that
  6801.   everything that can be done with  a data  structure can  be done  with an
  6802.   object type.
  6803.  
  6804.  
  6805.  
  6806.   8.3 Inheritance.
  6807.  
  6808.   In the  definition of an object type it is possible to inherit fields and
  6809.   methods from a previous defined object types. This is done  by placing an
  6810.   INHERIT line in the start of the structure definition.
  6811.  
  6812.  
  6813.   Example:  In a  school you have pupils and teachers. They are all persons
  6814.     but have different additional properties. Pupils are members of a class
  6815.     and have  parents, while the teachers teaches in special subjects (like
  6816.     mathematics, computer sience, physics etc.) and they have their monthly
  6817.     salary.
  6818.  
  6819.     Two object types Pupil and Teacher can be defined in this way:
  6820.  
  6821.       STRUC Pupil
  6822.         INHERIT Person
  6823.  
  6824.         DIM Class OF BYTE
  6825.         DIM Mother$ OF 30
  6826.         DIM Father$ OF 30
  6827.  
  6828.         PROC Print
  6829.           Person.Print
  6830.           PRINT
  6831.           PRINT "Class:  ",Class
  6832.           PRINT "Mother: ",Mother$
  6833.           PRINT "Father: ",Father$
  6834.         ENDPROC Print
  6835.  
  6836.       ENDSTRUC Pupil
  6837.  
  6838.       STRUC Teacher
  6839.         INHERIT Person
  6840.  
  6841.                                          120
  6842.  
  6843.  
  6844.  
  6845.  
  6846.  
  6847.  
  6848.         DIM Subject OF UBYTE
  6849.         DIM Salary OF FLOAT
  6850.  
  6851.         PROC Print
  6852.           Person.Print
  6853.           PRINT
  6854.           PRINT "Subject: ",Subject
  6855.           PRINT "Salary:  ",Salary
  6856.         ENDPROC Print
  6857.  
  6858.       ENDSTRUC Teacher
  6859.  
  6860.  
  6861.   All the fields and all the methods of the inherited are accessible from the
  6862.   descendant object type and from the outside world as if they were directly
  6863.   defined in this object type. If a method in the descendant object has the
  6864.   same name as a method in the ancestor object, the child method will over-
  6865.   load the  method in  the ancestor object. This is the case with the Print
  6866.   method in the example.  The overloaded  method may  be accessed  by using
  6867.   the dot notation.
  6868.  
  6869.  
  6870.   Example: A general stack type can be made in this way:
  6871.  
  6872.       STRUC Stack
  6873.         DIM StackTop OF NodePtr
  6874.  
  6875.         PROC Push(REF Element OF NodePtr)
  6876.           Element@.Next:=StackTop
  6877.           StackTop:=Element
  6878.         ENDPROC Push
  6879.  
  6880.         PROC Pop(REF Element OF NodePtr)
  6881.           Element:=StackTop
  6882.           IF StackTop<>0 THEN
  6883.             StackTop:=StackTop@.Next
  6884.         ENDPROC
  6885.       ENDSTRUC Stack
  6886.  
  6887.       STRUC StackNode
  6888.         DIM Next OF POINTER TO StackNode
  6889.       ENDSTRUC StackNode
  6890.  
  6891.       TYPE NodePtr=POINTER TO StackNode
  6892.  
  6893.  
  6894.     To store a someting on the stack, for example a long integer, we can de-
  6895.     fine a NumberNode:
  6896.  
  6897.  
  6898.                                          121
  6899.  
  6900.  
  6901.  
  6902.  
  6903.  
  6904.       STRUC NumberNode
  6905.         INHERIT StackNode
  6906.         DIM Num OF LONG
  6907.       ENDSTRUC NumberNode
  6908.  
  6909.     and then execute statements like:
  6910.  
  6911.       DIM Stack OF Stack
  6912.       DIM NumPtr OF POINTER TO NumberNode
  6913.  
  6914.       ALLOCATE(NumPtr)
  6915.       Stack.Pusk(NumPtr)
  6916.  
  6917.     The elements of the stack need not all be of  the same  type. They only
  6918.     need to be objects that are descendants of the StackNode object.
  6919.  
  6920.  
  6921.   A structure A is assignment compatible to a structure B, i.e. an assignment
  6922.   of the form A:=B can be made, if A and B have the same type or if A's ty-
  6923.   pe is  the ancestor  of B's  type. That's  why the variable NumPtr in the
  6924.   example can be used as the actual parameter to the  formal parameter Ele-
  6925.   ment in the method Push.
  6926.  
  6927.  
  6928.   8.4 Virtual methods.
  6929.  
  6930.   If the  Print method was called from the Input method in the Pupil object
  6931.   in the section 9.3, it would have been the ancestors Print method, i.e. the
  6932.   fields of the descendant (Class, Mother$ and Father$) would not be printed.
  6933.  
  6934.   It is possible to force the system to call the method of the youngest des-
  6935.   cendant (if any) by specifying the method as virtual. A virtual method is
  6936.   defined by using a procedure/function head of the form:
  6937.  
  6938.     PROC func_name[(formal_parameter_list)] VIRTUAL
  6939.  
  6940.   or 
  6941.  
  6942.     FUNC func_name[(formal_parameter_list)] [OF NumType] VIRTUAL
  6943.  
  6944.   Example: This example shows a definition of different figures constituing a
  6945.     class hierarchy. The point is the base figure. The circle and the ractangle
  6946.     shares proporties with this but each one has its own characteristics:
  6947.  
  6948.     STRUC Point
  6949.       USE Graphics
  6950.  
  6951.       DIM PosX OF FLOAT, PosY OF FLOAT
  6952.       DIM FigureColor OF BYTE
  6953.  
  6954.  
  6955.                                          122
  6956.  
  6957.  
  6958.  
  6959.  
  6960.  
  6961.       PROC Init(x,y,Color OF BYTE)
  6962.         PosX:=x; PosY:=y
  6963.         FigureColor:=Color
  6964.         pencolor(FigureColor)
  6965.         moveto(x,y)
  6966.         Draw
  6967.       ENDPROC Init
  6968.  
  6969.       PROC Move(dx,dy)
  6970.         pencolor(0)
  6971.         moveto(PosX,PosY)
  6972.         Draw
  6973.         pencolor(FigureColor)
  6974.         PosX:+dx; PosY:+dy
  6975.         moveto(PosX,PosY)
  6976.         Draw
  6977.       ENDPROC Move
  6978.  
  6979.       PROC Draw VIRTUAL   // Virtual method
  6980.         plot(PosX,PosY)   // Defines the form of the figure
  6981.       ENDPROC Draw
  6982.  
  6983.     ENDSTRUC Point
  6984.  
  6985.     STRUC Circle
  6986.       INHERIT Point
  6987.  
  6988.       USE Graphics
  6989.  
  6990.       DIM Radius OF FLOAT
  6991.  
  6992.       PROC Init(x,y,Color OF BYTE,R)
  6993.         Radius:=R
  6994.         Point.Init(x,y,Color)
  6995.       ENDPROC Init
  6996.  
  6997.       PROC Draw
  6998.         circle(PosX,PosY,Radius)
  6999.       ENDPROC Draw
  7000.     ENDSTRUC Circle
  7001.  
  7002.     STRUC Rectangle
  7003.       INHERIT Point
  7004.  
  7005.       USE Graphics
  7006.  
  7007.       DIM Height OF FLOAT, Width OF FLOAT
  7008.  
  7009.       PROC Init(x,y,Color OF BYTE,h,w)
  7010.         Height:=h
  7011.  
  7012.                                          123
  7013.  
  7014.  
  7015.  
  7016.  
  7017.  
  7018.         Width:=w
  7019.         Point.Init(x,y,Color)
  7020.       ENDPROC Init
  7021.  
  7022.       PROC Draw
  7023.         draw(Width,0)
  7024.         draw(0,Height)
  7025.         draw(-Width,0)
  7026.         draw(0,-Height)
  7027.       ENDPROC Draw
  7028.  
  7029.     ENDSTRUC Rectangle
  7030.  
  7031.  
  7032.     STRUC Square
  7033.       INHERIT Rectangle
  7034.  
  7035.       PROC Init(x,y,Color OF BYTE,s)
  7036.         Rectangle.Init(x,y,Color,s,s)
  7037.       ENDPROC Init
  7038.  
  7039.     ENDSTRUC Square
  7040.  
  7041.  
  7042.   If you are using pointers to structures containing virtual methods it may be
  7043.   necessary to store a method table in the data field of the structure. You
  7044.   have to tell Comal that you want this table by using the line
  7045.  
  7046.     METHODTABLE
  7047.  
  7048.   in the start of the structure.
  7049.  
  7050.  
  7051.   Example: This structure is the ScreenClass defined in the module CITScreen:
  7052.  
  7053.  
  7054.     STRUC ScreenClass
  7055.       METHODTABLE
  7056.  
  7057.       FUNC CreateObject(REF Screen OF Screen) OF SHORT VIRTUAL
  7058.         RETURN TRUE
  7059.       ENDFUNC CreateObject
  7060.  
  7061.       PROC DeleteObject(REF Screen OF Screen) VIRTUAL
  7062.       ENDPROC DeleteObject
  7063.  
  7064.     ENDSTRUC ScreenClass
  7065.  
  7066.  
  7067.  
  7068.  
  7069.                                          124
  7070.  
  7071.  
  7072.  
  7073.  
  7074.  
  7075.   NOTE: If a  method table  is stored  in the data field you cannot use the
  7076.   structure in a call to an external (C programmed) routine (for instance a
  7077.   system routine).
  7078.  
  7079.  
  7080.   8.5 Constructors.
  7081.  
  7082.   Sometimes an object needs to be initialized before it can be used.
  7083.  
  7084.  
  7085.   Example:  One of the basic structures of the Amiga operating system is the
  7086.     List structure:
  7087.  
  7088.       STRUC List
  7089.         DIM lh_Head OF POINTER TO Node
  7090.         DIM lh_Tail OF POINTER TO Node
  7091.         DIM lh_TailPred OF POINTER TO Node
  7092.         DIM lh_Type OF UBYTE
  7093.         DIM lh_pad OF UBYTE
  7094.       ENDSTRUC List
  7095.  
  7096.     which is a double ended list used to store nodes of the form:
  7097.  
  7098.       STRUC Node
  7099.         DIM ln_Succ OF POINTER TO Node
  7100.         DIM ln_Pred OF POINTER TO Node
  7101.         DIM ln_Type OF BYTE
  7102.         DIM ln_Pri OF BYTE
  7103.         DIM ln_Name OF ULONG
  7104.       ENDSTRUC Node
  7105.  
  7106.     Before the list can be used it has to be initialized to an empty list by
  7107.     executing statements like:
  7108.  
  7109.       lh_Head:=ADR(lh_Tail)
  7110.       lh_TailPred:=ADR(lh_Head)
  7111.       lh_Tail:=0
  7112.  
  7113.  
  7114.   If the initiatization of an object does not require parameters (like the ini-
  7115.   tialization of List in the example) it can be put into a method that is de-
  7116.   clared as  a constructor  method. A constructor method is a method with a
  7117.   head of the form:
  7118.  
  7119.     FUNC func_name CONSTRUCTOR
  7120.  
  7121.  
  7122.   Such a method is called automatically when the object is created as a static
  7123.   variable in  a DIM or LOCAL statement or is created as a dynamic variable
  7124.   by executing the ALLOCATE procedure.
  7125.  
  7126.                                          125
  7127.  
  7128.  
  7129.  
  7130.  
  7131.  
  7132.  
  7133.   A constructor returns a SHORT integer value to be considered as a boolean
  7134.   value. TRUE (=1) if the initialization succeded. FALSE (=0) otherwise.
  7135.  
  7136.   Example:  A smarter definition of the List object is the following:
  7137.  
  7138.       STRUC List
  7139.         DIM lh_Head OF POINTER TO Node
  7140.         DIM lh_Tail OF POINTER TO Node
  7141.         DIM lh_TailPred OF POINTER TO Node
  7142.         DIM lh_Type OF UBYTE
  7143.         DIM lh_pad OF UBYTE
  7144.  
  7145.         FUNC New CONSTRUCTOR
  7146.           lh_Head:=ADR(lh_Tail)
  7147.           lh_TailPred:=ADR(lh_Head)
  7148.           lh_Tail:=0
  7149.           RETURN TRUE
  7150.         ENDFUNC New
  7151.  
  7152.       ENDSTRUC List
  7153.  
  7154.     The List  in the  module ExecLists found in the directory SystemModules
  7155.     is defined in this way.
  7156.  
  7157.  
  7158.   If a field is an object containing a constructor this constructor is called,
  7159.   too. If  an object  inherits other  objects all the ancestors constructor
  7160.   methods are called when an object of that type is created. But you should
  7161.   note that  the virtual  method calling mechanism does not function at the
  7162.   initialization time (the descendants are not initialized until after all the
  7163.   ancestors have been initialized).
  7164.  
  7165.   If a constructor returns FALSE, all the destructors (see next section) of
  7166.   the sub objects (fields or inherited objects) that has been successfully ini-
  7167.   tialized, will be called.
  7168.  
  7169.  
  7170.  
  7171.   8.6 Destructors.
  7172.  
  7173.   If an object needs to do some cleaning up before its data fields are remo-
  7174.   ved you can declare a method as a  destructor. A  destructor method  is a
  7175.   method of the form:
  7176.  
  7177.     PROC proc_name DESTRUCTOR
  7178.  
  7179.  
  7180.   Such a  method is  called whenever  the memory  used by  the objects data
  7181.   field is removed. This will be the case if DEALLOCATE  is called  or at a
  7182.  
  7183.                                          126
  7184.  
  7185.  
  7186.  
  7187.  
  7188.  
  7189.   return from a procedure or function (if the object is a local variable). But
  7190.   a constructor may also be called when all the variables are cleared, i.e af-
  7191.   ter the program has stopped!
  7192.  
  7193.   Because destructors are called in many different sitiuations a destructor
  7194.   method should be as short as possible, it should do no IO and it should be
  7195.   free of errors!
  7196.  
  7197.   The best  way to  develop constructors is to first activate them manually
  7198.   (leave out the word CONSTRUCTOR). Then,  when  you  think  it  works, add
  7199.   the word CONSTRUCTOR.
  7200.  
  7201.  
  7202.   Example: One  of the  basic elements of the Amiga multy tasking system is
  7203.     the message port. A message port consists of a list node (such  that it
  7204.     can be put into the list of public ports if desired) and some fields.
  7205.  
  7206.     One of the fields contains the number of a signal bit that has to be allo-
  7207.     cated when the port is created and it  has to  be deallocated  when the
  7208.     port is  removed. Another field is a list where messages can be placed.
  7209.     Also this has to be initialized.
  7210.  
  7211.     The alocation of a signal bit can be done in a constructor and the deal-
  7212.     location in a destructor. A message port can be defined in this way:
  7213.  
  7214.       STRUC MsgPort
  7215.         INHERIT Node
  7216.  
  7217.         USE ExecLibrary
  7218.         USE ExecLists
  7219.  
  7220.         DIM mp_Flags OF UBYTE
  7221.         DIM mp_SigBit OF BYTE
  7222.         DIM mp_SigTask OF ULONG
  7223.         DIM mp_MsgList OF List
  7224.  
  7225.         FUNC Init CONSTRUCTOR
  7226.           ln_Type:=NT_MSGPORT
  7227.           mp_SigTask:=FindTask($0)
  7228.           mp_SigBit:=AllocSignal(-1)
  7229.           RETURN mp_SigBit>=0         // No signals if mp_SigBit<0
  7230.         ENDFUNC Init
  7231.  
  7232.         PROC Delete DESTRUCTOR
  7233.           IF ln_Name<>0 THEN
  7234.             RemPort(ADR(Node))
  7235.             ln_Name:=0
  7236.           ENDIF
  7237.           IF mp_SigBit>=0 THEN
  7238.             FreeSignal(mp_SigBit)
  7239.  
  7240.                                          127
  7241.  
  7242.  
  7243.  
  7244.  
  7245.  
  7246.           ENDIF
  7247.         ENDPROC Delete
  7248.  
  7249.       ENDSTRUC MsgPort
  7250.  
  7251.     Note that the list mp_MsgList is not initialized in the constructor shown.
  7252.     But this list is imported from the module ExecLists and the list in this
  7253.     moule contains a constructor that will do the initialization.
  7254.  
  7255.  
  7256.  
  7257.   9 Modules.
  7258.  
  7259.   A module  is a  program structure  used to  devide a program into smaller
  7260.   parts. A module contains variables, procedures, functions and type defini-
  7261.   tions that can be use outside the module.
  7262.  
  7263.  
  7264.   9.1 Making modules.
  7265.  
  7266.   A module has the form:
  7267.  
  7268.     MODULE ModuleName
  7269.  
  7270.       [USE statements]
  7271.  
  7272.       [EXPORT statements]
  7273.  
  7274.       <normal program lines>
  7275.  
  7276.     ENDMODULE ModuleName
  7277.  
  7278.  
  7279.   Example:
  7280.  
  7281.       MODULE Hyperbolic
  7282.  
  7283.         EXPORT sinh,cosh
  7284.  
  7285.         FUNC sinh(x)
  7286.           RETURN (EXP(x)-EXP(-x))/2
  7287.         ENDFUNC sinh
  7288.  
  7289.         FUNC cosh(x)
  7290.           RETURN (EXP(x)+EXP(-x))/2
  7291.         ENDFUNC cosh
  7292.  
  7293.       ENDMODULE Hyperbolic
  7294.  
  7295.  
  7296.  
  7297.                                          128
  7298.  
  7299.  
  7300.  
  7301.  
  7302.  
  7303.   All procedures, functions and variables are strictly local to the module. On-
  7304.   ly those names that are exported  in EXPORT  statements can  be used out-
  7305.   side the module. An EXPORT statement has the form:
  7306.  
  7307.     EXPORT ExportList
  7308.  
  7309.   where ExportList is one or more of the following separated by commas (,):
  7310.  
  7311.     Identifier [AS ExportName]
  7312.  
  7313.  
  7314.   If the AS part is present the ExportName is used in references to the ex-
  7315.   ported element. Otherwise it is referenced by the name used inside the mo-
  7316.   dule itself.
  7317.  
  7318.  
  7319.   Example: If the EXPORT statement in the previous example is changed to
  7320.  
  7321.       EXPORT sinh,sinh AS SINH,cosh,cosh AS COSH
  7322.  
  7323.     both sinh and SINH can be used to refer to the sinh function (and similar
  7324.     for cosh).
  7325.  
  7326.  
  7327.   It is possible to export names that are imported from other modules. This is
  7328.   called re-export.
  7329.  
  7330.   A module can be placed in the program that uses the module (local module)
  7331.   or it can be placed in a separate disk file (external modules). There is no
  7332.   limit to  the number  of modules  that can be placed in a program or in a
  7333.   disk file.
  7334.  
  7335.   An external module is best made by first make it as a local module. Then,
  7336.   when you  think it  works, store it on disk in code form (open a new pro-
  7337.   ject, use the clipboard to move the module  to the  new project  and then
  7338.   save the module using the Save item in the Program menu).
  7339.  
  7340.  
  7341.  
  7342.   9.2 Using modules.
  7343.  
  7344.   The exported names in a module (including type names) are made accessible
  7345.   by a USE statement. A USE statement has form:
  7346.  
  7347.     USE ModuleName [FROM FileName]
  7348.  
  7349.  
  7350.   Example:
  7351.     USE System
  7352.     USE Hyperbolic FROM MathModule
  7353.  
  7354.                                          129
  7355.  
  7356.  
  7357.  
  7358.  
  7359.  
  7360.  
  7361.  
  7362.   All USE statements are executed at the scanning  time. If  the USE state-
  7363.   ment is  used without the FROM part the system searches for the module in
  7364.   the following way:
  7365.  
  7366.     1. among the local modules
  7367.     2. in a file Comal:Modules/ModuleName.mod (if it exists)
  7368.     3. in a file Comal:SystemModules/ModuleName.mod (if it exists)
  7369.     4. in a file Comal:Modules/ModuleName (mashine coded module)
  7370.     5. in a file Comal:SystemModules/ModuleName (mashine coded module)
  7371.  
  7372.  
  7373.   If the file in 2. or 3. is found there must be one module by name Module-
  7374.   Name in this file.
  7375.  
  7376.   If the second form of the USE statement is used, the specified file is loa-
  7377.   ded and if it is a Comal module (.mod file) there must  be one  module by
  7378.   name ModuleName in this file.
  7379.  
  7380.   A USE statement can be placed in a program, in an object, in a closed pro-
  7381.   cedure or function or in a module, and all the type names and all the ex-
  7382.   ported names  in the  module used can be accessed in the scope of the USE
  7383.   statement.
  7384.  
  7385.  
  7386.   9.3 Signal procedures.
  7387.  
  7388.   It is possible to make the module recieve  messages about  changes in the
  7389.   system. These messages are send as signal numbers to a procedure declared
  7390.   as a signal procedure.
  7391.  
  7392.   The head of a signal procedure has the form:
  7393.  
  7394.     PROC ProcName(Sig OF LONG) SIGNAL
  7395.  
  7396.  
  7397.   Example:
  7398.  
  7399.       PROC Signal(s OF LONG) SIGNAL
  7400.         CASE s OF
  7401.         WHEN SIG_DISCARD
  7402.           CleanUp
  7403.         OTHERWISE
  7404.           // No action
  7405.         ENDCASE
  7406.       ENDPROC Signal
  7407.  
  7408.  
  7409.   The signal numbers send and their meanings are:
  7410.  
  7411.                                          130
  7412.  
  7413.  
  7414.  
  7415.  
  7416.  
  7417.  
  7418.     SIG_CLOSE (1)       send if interpreter is going to close
  7419.     SIG_DISCARD (2)     send if the module is being removed
  7420.     SIG_CLEAR (3)       send if all variables in main program are cleared
  7421.     SIG_RUN (4)         send before execution starts
  7422.     SIG_STOP (5)        send at program stop that can be continued
  7423.     SIG_END (6)         send at program stop that cannot be continued
  7424.     SIG_STARTTRACE (7)  send at change to trace mode
  7425.     SIG_STOPTRACE (8)   send if trace mode ends
  7426.     SIG_STEP (9)        send if a step is executed in trace mode
  7427.     SIG_CONTINUE (10)   send if program execution continues after stop
  7428.  
  7429.  
  7430.   The symbolic names used are defined in the System module.
  7431.  
  7432.   NOTE! Signal numbers send to a module should not be  confused with signal
  7433.   numbers used in the Amiga operating system.
  7434.  
  7435.  
  7436.  
  7437.   10 Description of the standard modules.
  7438.  
  7439.   In the  directory SystemModules a number of useful modules are found. The
  7440.   content of some of these modules will be described in this section.
  7441.  
  7442.  
  7443.   10.1 The System modules.
  7444.  
  7445.   As is the case with other implementations of Comal the system module con-
  7446.   tains implementation  dependent stuff.  In this implementation the system
  7447.   module is devided into two parts: A module written in Comal by  name Sys-
  7448.   tem, and a machine coded module by name SystemCode.
  7449.  
  7450.  
  7451.   10.1.1 SystemCode.
  7452.  
  7453.   This module contains the following procedures and functions:
  7454.  
  7455.  
  7456.     FUNC ComalStrucAdr OF ULONG
  7457.  
  7458.       Returns the  address of the ComalStruc (see description of the System
  7459.       module in next section).
  7460.  
  7461.  
  7462.     FUNC CharArrayToString$(Array OF ULONG)
  7463.  
  7464.       Converts a null terminated array of characters into a Comal string.
  7465.  
  7466.  
  7467.  
  7468.                                          131
  7469.  
  7470.  
  7471.  
  7472.  
  7473.  
  7474.     FUNC ComalWait(SignalMask OF ULONG) OF ULONG
  7475.  
  7476.       This function is used like the function Wait in the Exec library of the
  7477.       Amiga operating system.
  7478.  
  7479.       The function OR's all the Comal signals to the actual parameter Signal-
  7480.       Mask and then calls Wait. Among  other things  this means  that it is
  7481.       possible to break a Comal program that has called ComalWait (this can-
  7482.       not be done if Wait is called!)
  7483.  
  7484.       The return value is a mask containing the signals that caused the re-
  7485.       turn (and this may be one of the Comal signals).
  7486.  
  7487.  
  7488.     FUNC SysLibVersion OF USHORT
  7489.  
  7490.       Returns the current version of your system.
  7491.  
  7492.  
  7493.     FUNC LockComalWindow OF ULONG
  7494.  
  7495.       Get a  shared lock  for the standard IO window. The return value is a
  7496.       pointer to the standard IO window.
  7497.  
  7498.  
  7499.     PROC UnlockComalWindow
  7500.  
  7501.       Call this procedure when the pointer  returned by  LockComalWindow is
  7502.       not needed any longer.
  7503.  
  7504.  
  7505.     PROC AddSignal(SigMask OF ULONG)
  7506.  
  7507.       Call this routine if you want one or more signals to be a Comal signal.
  7508.       The arrival of a Comal signal will cause ComalWait to  return and the
  7509.       sleep state started by the WAIT statement (see sectio 7.2) will be ter-
  7510.       minated. The actual parameter is a mask of signals.
  7511.  
  7512.  
  7513.     PROC RemSignal(SigMask OF ULONG)
  7514.  
  7515.       Removes a Comal signal added by AddSignal.
  7516.  
  7517.  
  7518.     PROC AddComalDevice(IoDevice OF ULONG)
  7519.  
  7520.       Call this procedure if you want to add a new IO device to the list of
  7521.       standard devices (like "ds:", "kb:" and "lp:"). The actual parameter must
  7522.       be a pointer to an initialized device structure.
  7523.  
  7524.  
  7525.                                          132
  7526.  
  7527.  
  7528.  
  7529.  
  7530.  
  7531.  
  7532.     PROC RemComalDevice(IoDevice OF ULONG)
  7533.  
  7534.       Call this with a pointer to the IO device you want to remove from the
  7535.       list of IO devices.
  7536.  
  7537.  
  7538.     PROC AddExcept(ExceptStruc OF ULONG)
  7539.  
  7540.       Call this procedure if you want to add an exception routine to the list
  7541.       of exception routines. The actual parameter must be  a pointer  to an
  7542.       initialized exception structure.
  7543.  
  7544.  
  7545.     PROC RemExcept(ExceptStruc OF ULONG)
  7546.  
  7547.       Call this with a pointer to the exception structure you want to remove
  7548.       from the list of exception routines.
  7549.  
  7550.  
  7551.   Although it is possible to use a Comal procedure as  an exception routine
  7552.   the last two routines are normally not used from Comal. Use the procedures
  7553.   ADDINTERRUPT and REMINTERRUPT in stead (see section 7.5).
  7554.  
  7555.  
  7556.  
  7557.   10.1.2 System.
  7558.  
  7559.   The System  module uses  the SystemCode  module from  where the functions
  7560.   CharArrayToString$ and  ComalWait is re-exported. Two routines are expor-
  7561.   ted:
  7562.  
  7563.     FUNC ComalPath$
  7564.  
  7565.       Returns a string containing the complete path of your comal system.
  7566.  
  7567.  
  7568.     FUNC StartupArg$(n OF USHORT)
  7569.  
  7570.       Returns the n'the startup argument (if started from the Shell) or the
  7571.       n'the tool type (if started from Workbench). If n is out of range (zero
  7572.       or too large) the empty string is returned.
  7573.  
  7574.       For the time being this function is of no interest if the Comal program
  7575.       is started from the editor.
  7576.  
  7577.  
  7578.  
  7579.   In this module the Comal structure is defined:
  7580.  
  7581.  
  7582.                                          133
  7583.  
  7584.  
  7585.  
  7586.  
  7587.  
  7588.     STRUC ComalStruc
  7589.       DIM BreakFlags OF UBYTE
  7590.       DIM SecBreakFlags OF UBYTE
  7591.       DIM Flags OF USHORT
  7592.       DIM CurrWorkBottom OF POINTER TO UBYTE
  7593.       DIM CurrWorkTop OF POINTER TO UBYTE
  7594.       DIM MinStack OF POINTER TO UBYTE
  7595.       DIM IO_Screen OF POINTER TO Screen
  7596.       DIM CommPort OF POINTER TO MsgPort
  7597.       DIM AsciiId OF POINTER TO UBYTE
  7598.       DIM MainPrgBuf OF POINTER TO PrgBuf
  7599.       DIM PrgEnv OF POINTER TO PrgEnv
  7600.       DIM WorkStart OF ULONG
  7601.       DIM WorkEnd OF ULONG
  7602.       DIM WorkLength OF ULONG
  7603.       DIM SortTable OF POINTER TO UBYTE
  7604.       DIM ComalPath OF POINTER TO UBYTE
  7605.       DIM Parameters OF POINTER TO ULONG
  7606.     ENDSTRUC ComalStruc
  7607.  
  7608.  
  7609.   Only a few fields are of interest for Comal programmers:
  7610.  
  7611.     IO_Screen
  7612.  
  7613.       A pointer to the screen where all windows should be placed. This poin-
  7614.       ter is non zero even if the screen is the Workbench screen.
  7615.  
  7616.  
  7617.     CommPort
  7618.  
  7619.       If non zero this is a pointer to a message port allocated for you.
  7620.  
  7621.  
  7622.     AsciiId
  7623.  
  7624.       This is a pointer to a null terminated array of characters that identi-
  7625.       fies this interpreter process.
  7626.  
  7627.  
  7628.     SortTable
  7629.  
  7630.       This is a pointer to a table of sort values used when strings are com-
  7631.       pared. Normally it is filled with the ASCII values.
  7632.  
  7633.       It is possible to change the content of the table (do not  change the
  7634.       pointer itself!) with other sorting values.
  7635.  
  7636.       Example: By  using this little code upper and lower case letters will
  7637.         have the same sorting values:
  7638.  
  7639.                                          134
  7640.  
  7641.  
  7642.  
  7643.  
  7644.  
  7645.  
  7646.           FOR i:=ORD("a") TO ORD("z") DO
  7647.             ComalStruc@.SortTable(i):=i-32
  7648.           ENDFOR i
  7649.  
  7650.  
  7651.     ComalPath
  7652.  
  7653.       This is a pointer to a null terminated string containing the complete
  7654.       path of your comal system.
  7655.  
  7656.  
  7657.     Parameters
  7658.  
  7659.       This is a pointer to an array of pointers to null terninated strings (the
  7660.       startup arguments). The array is terminated by a null pointer.
  7661.  
  7662.  
  7663.   A pointer ComalStruc to the Comal structure is exported.
  7664.  
  7665.   The following useful types are defined in the module:
  7666.  
  7667.     TYPE BOOL=BYTE
  7668.     TYPE bool=BYTE
  7669.     TYPE WORD=SHORT
  7670.     TYPE word=SHORT
  7671.     TYPE UWORD=USHORT
  7672.     TYPE uword=USHORT
  7673.  
  7674.  
  7675.   The signal numbers SIG_CLOSE,  SIG_DISCARD  etc.  (see  section  9.3) and
  7676.   the memory  types MEMF_PUBLIC  etc. (see section 1.4) are defined and ex-
  7677.   ported from the module.
  7678.  
  7679.  
  7680.  
  7681.   10.2 The graphics modules.
  7682.  
  7683.   Two graphics modules Graphics and Turtle can be used.
  7684.  
  7685.  
  7686.  
  7687.   10.2.1 Graphics.
  7688.  
  7689.   This module is compatibal with graphics modules (packages) found in other
  7690.   implementations  of  Comal  (UniComal  for  the  C64  and PC'c and Amiga-
  7691.   COMAL v. 2.x).
  7692.  
  7693.   The Graphics module contains:
  7694.  
  7695.  
  7696.                                          135
  7697.  
  7698.  
  7699.  
  7700.  
  7701.  
  7702.     PROC arc(c1,c2,r,start_angle,arc)
  7703.  
  7704.       The procedure causes an arc to be drawn with its center at (c1,c2) and
  7705.       with a radius r. The arc has the length arc degrees starting with the
  7706.       angle start_angle.
  7707.  
  7708.       Exampel:
  7709.  
  7710.         arc(100,100,50,45,90)
  7711.         arc(x0,y0,r,v,2*v)
  7712.  
  7713.  
  7714.     PROC background(color)
  7715.  
  7716.       This procedure sets the back ground color to the value of the parame-
  7717.       ter color.
  7718.  
  7719.       Exampel:
  7720.  
  7721.         background(3) // Set back ground color to blue (red in WB 1.3)
  7722.  
  7723.  
  7724.     PROC circle(c1,c2,r)
  7725.  
  7726.       Draws a circle with its center at (c1,c2) and with radius r. The drawn
  7727.       figure will not be a round circle unless a suitable relation between the
  7728.       vertical and horizontal units has been chosen (window procedure).
  7729.     
  7730.       The current pen position is unchanged.
  7731.  
  7732.       Exampel:
  7733.  
  7734.         window(-160,160,-100,100)
  7735.         circle(0,0,50)              // Draw a "circular" circle.
  7736.  
  7737.  
  7738.     PROC clear
  7739.  
  7740.       Clears the window inside the current drawing region set by the proce-
  7741.       dure clip.
  7742.  
  7743.  
  7744.     PROC clearscreen
  7745.  
  7746.       Clears the window inside the current viewport frame set by the proce-
  7747.       dure viewport.
  7748.  
  7749.  
  7750.  
  7751.  
  7752.  
  7753.                                          136
  7754.  
  7755.  
  7756.  
  7757.  
  7758.  
  7759.     PROC clip(xmin,xmax,ymin,ymax)
  7760.  
  7761.       The procedure clip defines a working region expressed in window coor-
  7762.       dinates (se window procedure). All drawings (clear, fill, draw, ....) can-
  7763.       not be seen outside this region.
  7764.  
  7765.       Exampel:
  7766.  
  7767.         clip(2.5,4.7,-2,0)
  7768.         clip(0,cx,cy,cy+10)
  7769.  
  7770.  
  7771.     FUNC depth
  7772.  
  7773.       Function that returns the depth of the graphics window (the number of
  7774.       bitmaps in the window).
  7775.  
  7776.       If the depth is 2, there are four colors with numbers 0-3. The number
  7777.       of colors can always be calculated as
  7778.  
  7779.         colornumber:=2^depth
  7780.  
  7781.  
  7782.     PROC draw(x,y)
  7783.  
  7784.       Draws a  line from the current pen position (x0,y0) to the point with
  7785.       coordinates (x0+x,y0+y).
  7786.     
  7787.       The new pen position is the point with coordinates (x0+x,y0+y).
  7788.  
  7789.       Exampel:
  7790.  
  7791.         draw(0,100)  // Draws a vertical line of length 101
  7792.  
  7793.  
  7794.     PROC drawto(x,y)
  7795.  
  7796.       Draws a line from the current pen position (x0,y0) to  the point with
  7797.       coordinates (x,y).
  7798.     
  7799.       The new pen position is the point with coordinates (x,y).
  7800.  
  7801.  
  7802.     PROC fill(x,y)
  7803.  
  7804.       Fills an area with the current pencolor. The area to be filled must con-
  7805.       tain the point (x,y) and be bounded by either a curve in a color diffe-
  7806.       rent from the background color or by the frame set by the clip.
  7807.     
  7808.       The current pen position is unchanged.
  7809.  
  7810.                                          137
  7811.  
  7812.  
  7813.  
  7814.  
  7815.  
  7816.  
  7817.       Exampel:
  7818.         pencolor(1)
  7819.         circle(300,100,50)  // Draw a circle with pencolor 1
  7820.         pencolor(2)
  7821.         fill(300,100)       // .. and fill with pencolor 2
  7822.  
  7823.  
  7824.     FUNC getcolor(x,y)
  7825.  
  7826.       Return color of the point with coordinates (x,y).
  7827.     
  7828.       The current pen position is unchanged.
  7829.  
  7830.  
  7831.     FUNC getrgb(color_register)
  7832.  
  7833.       Returns the color of the specified color register. Written as a hexade-
  7834.       cimal number the content is of the form
  7835.  
  7836.         $0rgb
  7837.  
  7838.       where r, g and b are  the content  of the  red, green  and blue color
  7839.       (four bits for each color).
  7840.  
  7841.       If the graphics system is not opned the value -1 is returned.
  7842.              
  7843.  
  7844.     PROC graphicscreen(Window)
  7845.  
  7846.       Opens the graphics system. If the actual parameter is zero the standard
  7847.       IO-window will be used as the graphics window. If the parameter is non
  7848.       zero it  must be the address of a window and this window will be used
  7849.       as the graphics window.
  7850.  
  7851.       This procedure must be called before any of the graphics routines are
  7852.       called. When  the graphics  system is opned the command window or the
  7853.       graphics window may be brought in front by pressing <Shift>+<F1>.
  7854.       
  7855.  
  7856.     FUNC height
  7857.  
  7858.       Returns the height of the graphics window in pixels
  7859.     
  7860.  
  7861.     FUNC inq(no)
  7862.  
  7863.       The function inq returns certain of the internal variable of the gra-
  7864.       phics system. The parameter no must be an integral number in the ran-
  7865.       ge 0-33. The meaning of the returned value can be found in the follo-
  7866.  
  7867.                                          138
  7868.  
  7869.  
  7870.  
  7871.  
  7872.  
  7873.       wing table:
  7874.  
  7875.       number    information about     range     Affected by
  7876.         0       graphics mode         0/1       graphicscreen
  7877.         1
  7878.         2       text background       0-        textbackground
  7879.         3       text color            0-        pencolor
  7880.         4
  7881.         5       graphics backgruond   0-        background
  7882.         6       pen color             0-        pencolor
  7883.         7       graphics text width   8/10      textstyle
  7884.         8       graphics text height  8/10      textstyle
  7885.         9       gr. text direction    0         (dir. cannot be changed)
  7886.        10       graphics text mode    0/1       textstyle
  7887.        11
  7888.        12       pen inside dr. frame  0/1       most drawing procs
  7889.        13                             1
  7890.        14                             0
  7891.        15       wrapping active       0         (wrap not implemented)
  7892.        16       pen down              1         only changed in Turtle
  7893.        17       x-position            0-width   most drawing procs
  7894.        18       y-position            0-height  most drawing procs
  7895.        19       viewport xmin         0-width   viewport
  7896.        20       viewport xmax         0-width   viewport
  7897.        21       viewport ymin         0-height  viewport
  7898.        22       viewport ymax         0-height  viewport
  7899.        23       vindow xmin           real no.  window
  7900.        24       vindow xmax           real no.  window
  7901.        25       vindow ymin           real no.  window
  7902.        26       vindow ymax           real no.  window
  7903.        27                             1
  7904.        28                             0
  7905.        29                             0
  7906.        30       x-ratio               (rem. 1)  window and viewport
  7907.        31       y-ratio               (rem. 2)  window and viewport
  7908.        32                             0
  7909.        33                             0
  7910.  
  7911.       remark 1: (wdxmax-wdxmin)/(vpxmax-vpxmin)
  7912.       remark 2: (wdymax-wdymin)/(vpymax-vpymin)
  7913.  
  7914.  
  7915.     PROC interiorcolor(color)
  7916.  
  7917.       Subsequent calls to the procedure polygon uses the parameter color to
  7918.       fill out the interior of the polygon.
  7919.  
  7920.       Exampel:
  7921.         interiorcolor(2)    // Fill with black
  7922.         interiorcolor(-1)   // No filling
  7923.  
  7924.                                          139
  7925.  
  7926.  
  7927.  
  7928.  
  7929.  
  7930.  
  7931.  
  7932.     PROC loadscreen(name$)
  7933.  
  7934.       The procedure causes an ILBM-picture previous stored by  Comal (save-
  7935.       screen and  SaveWindow procedures) or by another program (like DeLuxe
  7936.       Paint) to be fetched from disk and placed in the graphics window.
  7937.  
  7938.       Exampel:
  7939.  
  7940.         loadscreen("MandelBrot.ilbm")
  7941.  
  7942.  
  7943.     PROC move(x,y)
  7944.  
  7945.       Moves witout drawing the pen from the current position (x0,y0) to the
  7946.       point with coordinates (x0+x,y0+y).
  7947.  
  7948.  
  7949.     PROC moveto(x,y)
  7950.  
  7951.       Moves witout drawing the pen to the point with coordinates (x,y).
  7952.  
  7953.  
  7954.     PROC noclip
  7955.  
  7956.       The procedure cancels any previously defined clip working region (set
  7957.       by the procedure clip) and restores the working region to the current
  7958.       viewport (set by the procedure viewport).
  7959.  
  7960.  
  7961.     PROC outlinecolor(color)
  7962.  
  7963.       Subsequent calls to the procedure polygon uses the parameter color as
  7964.       the color of the edges of the polygon.
  7965.  
  7966.       Exampel:
  7967.  
  7968.         outlinecolor(3)   // Draw polygon with edges in pencolor 3
  7969.  
  7970.  
  7971.     PROC paint(x,y)
  7972.  
  7973.       The procedure causes a region to be filled in with the current pencolor.
  7974.       The region  to be  filled must contain the point (x,y) and it must be
  7975.       limited by the pencolor or the viewport drawing area.
  7976.     
  7977.       The current pen position is unchanged.
  7978.     
  7979.  
  7980.  
  7981.                                          140
  7982.  
  7983.  
  7984.  
  7985.  
  7986.  
  7987.       Exampel:
  7988.  
  7989.         pencolor(1)
  7990.         moveto(0,0)
  7991.         drawto(500,150)     // Draw a black (white in WB 1.3) line
  7992.         pencolor(3)
  7993.         circle(300,100,50)  // .. a red circle
  7994.         paint(300,100)      // .. and fill the circle with blue color
  7995.  
  7996.  
  7997.     PROC palette(no)
  7998.  
  7999.       The procedure is used to set  the first  four colors  of the graphics
  8000.       screen. The colors are selected from one of three palettes:
  8001.      
  8002.         palette   color 0   color 1   color 2   color 3
  8003.         
  8004.            0       black     green      red      yellow
  8005.            1       black     magenta    cyan     white
  8006.  
  8007.       palette(-1) restores the colors to the original values.
  8008.      
  8009.       Note that  if the graphics window is placed in the IO-window (this is
  8010.       the case if the procedure graphicscreen is called with a zero as para-
  8011.       meter) all the Comal windows will change colors. The proceudre is im-
  8012.       plemented to insure compatibility with UniComals graphics module. Nor-
  8013.       mally the more general procedure setrgb should be used.
  8014.  
  8015.  
  8016.     FUNC pencolor(color)
  8017.  
  8018.       Procedure used to set the color of the pen.
  8019.  
  8020.  
  8021.     FUNC pixelx
  8022.  
  8023.       The function returns the width of a picture element (a pixel) expressed
  8024.       in the current window units.
  8025.  
  8026.       Exampel:
  8027.         draw(2*pixelx,0)
  8028.  
  8029.  
  8030.     FUNC pixely
  8031.  
  8032.       The function returns the height of a picture element (a pixel) expressed
  8033.       in the current window units.
  8034.  
  8035.       Exampel:
  8036.         draw(0,pixely)
  8037.  
  8038.                                          141
  8039.  
  8040.  
  8041.  
  8042.  
  8043.  
  8044.  
  8045.  
  8046.     PROCEDURE plot(x,y)
  8047.  
  8048.       The procedure places a dot at the point with coordinates (x,y).
  8049.  
  8050.       The current pen position is unchanged.
  8051.  
  8052.  
  8053.     PROC plottext(x,y,text$)
  8054.  
  8055.       The procedure causes text$ to be written in the graphics window star-
  8056.       ting at the point with coordinates (x,y).
  8057.  
  8058.       The current pen position is unchanged.
  8059.  
  8060.       Exampel:
  8061.  
  8062.         plottext(100,150,"Comal")
  8063.  
  8064.  
  8065.     PROC polygon(corners, REF x(), REF y())
  8066.  
  8067.       The procedure causes a polygon with corners vertices to be drawn. The
  8068.       coordinates of the vertices are stored in the vectors x() and y().
  8069.     
  8070.       The number of elements must be at least the value of corners.
  8071.     
  8072.       The edges (the perimeter) of the polygon is drawn in the color set by
  8073.       the procedure outlinecolor and the color of the inner region is set by
  8074.       the procedure interiorcolor (unless the interiorcolor is set to the value
  8075.       -1 in which case a transparent polygon will be drawn).
  8076.  
  8077.       Exampel:
  8078.  
  8079.         DIM x(3), y(3)
  8080.         READ x(),y()
  8081.         interiorcolor(3)
  8082.         outlinecolor(2)
  8083.         polygon(3,x(),y()) // Draw a triangle in color 3 with edges in color 2
  8084.         DATA 150,300,450
  8085.         DATA 20,150,20
  8086.  
  8087.       NOTE: The procedure uses a routine in the Amiga graphics  library. It
  8088.       seems as  if this  procedure has a bug. If the corners of the polygon
  8089.       falls outside the graphics window the system may crash (the well known
  8090.       GURU will visit you!).
  8091.  
  8092.  
  8093.  
  8094.  
  8095.                                          142
  8096.  
  8097.  
  8098.  
  8099.  
  8100.  
  8101.     PROC printscreen
  8102.  
  8103.       The procedure  transfers the  content of  the graphics  window to the
  8104.       printer.
  8105.  
  8106.  
  8107.     PROC savescreen(name$)
  8108.  
  8109.       The procedure causes the content of the graphics  window to  be saved
  8110.       on disk in ILBM format.
  8111.     
  8112.       Exampel:
  8113.  
  8114.         savescreen("MandelBrot.ilbm")
  8115.  
  8116.  
  8117.     PROC SaveWindow(name$,mode)
  8118.  
  8119.       The procedure  works as  savescreen above  if the  parameter mode has
  8120.       the value 0. If mode has the value 1 the window is saved in compressed
  8121.       form (using  the ByteRun1 compressing algorithm). This may reduce the
  8122.       size significantly.
  8123.  
  8124.       Exampel:
  8125.  
  8126.         SaveWindow("Mandelbrot.ilbm",1)
  8127.  
  8128.  
  8129.     PROC setrgb(color_register,red,green,blue)
  8130.  
  8131.       This procedure is used to set the amount of red, green and blue in the
  8132.       specified color register. The color_register is an integral number in the
  8133.       range 0-31 (this number is directly asociated to the color number used
  8134.       by the procedures pencolor, backcolor etc.) and the amount of color is
  8135.       an integral number in the range 0-15.
  8136.  
  8137.       Exampel: After the call
  8138.        
  8139.           setrgb(1,15,0,15)
  8140.         
  8141.         color number 1 (set by pencolor procedure) has the color magenta.
  8142.        
  8143.       The colors of all the color registers may be restore to their original
  8144.       value by palette(-1).
  8145.  
  8146.  
  8147.     PROC TextAttr(attr)
  8148.  
  8149.       The procedure  defines the manner in which the printout from the pro-
  8150.       cedure TextAttr will appear on the graphics window.
  8151.  
  8152.                                          143
  8153.  
  8154.  
  8155.  
  8156.  
  8157.  
  8158.  
  8159.       The following values may be used for the parameter attr:
  8160.  
  8161.          0  normal text
  8162.          1  bold
  8163.          2  italic
  8164.          4  underlined
  8165.          8  inverse
  8166.         16  only text (no background)
  8167.  
  8168.       More values can be set by adding the values.
  8169.  
  8170.       Exampel:
  8171.         TextAttr(1+2) // Print in bold and italic
  8172.  
  8173.  
  8174.     PROC textbackground(color)
  8175.  
  8176.       The procedure is used to set the background color used by the plottext
  8177.       procedure (see also textstyle).
  8178.  
  8179.  
  8180.     PROC textscreen
  8181.  
  8182.       Closes the graphics system.
  8183.  
  8184.  
  8185.     PROC textstyle(width#,height#,direction#,mode#)
  8186.  
  8187.       The proceudre  is implemented  to insure compatibility with UniComals
  8188.       graphics module and only the last parameter is significant. The meaning
  8189.       of this is:
  8190.  
  8191.          0  print without background
  8192.          1  print with background (as attr=16 in TextAttr above)
  8193.  
  8194.  
  8195.     PROC viewport(xmin,xmax,ymin,ymax)
  8196.  
  8197.       Defines a  region of  the graphics  window in which all drawings take
  8198.       place. The parameters refer to the physical window (pixel coordinates).
  8199.  
  8200.  
  8201.     PROC viewport_to_window(vpx, vpy, REF wdx, REF wdy)
  8202.  
  8203.       The procedure maps the viewport coordinates (the physical  window co-
  8204.       ordinates) to the window coordinates (set by the window procedure).
  8205.  
  8206.  
  8207.  
  8208.  
  8209.                                          144
  8210.  
  8211.  
  8212.  
  8213.  
  8214.  
  8215.     FUNC width
  8216.  
  8217.       The function returns the width of the graphics window in pixels.
  8218.  
  8219.  
  8220.     PROC window(xmin,xmax,ymin,ymax)
  8221.  
  8222.       The procedure defines a coordinate system in the current viewport. The
  8223.       parameter defines new coordinates for the border of the viewport.
  8224.  
  8225.  
  8226.     PROC window_to_viewport(wdx, wdy, REF vpx#, REF vpy#)
  8227.  
  8228.       The procedure converts window coordinates to  physical window coordi-
  8229.       nates (pixel coordinates).
  8230.  
  8231.  
  8232.     FUNC xcor
  8233.  
  8234.       The function returns the current x-coordinate of the pen.
  8235.  
  8236.  
  8237.     FUNC ycor
  8238.  
  8239.       The function returns the current y-coordinate of the pen.
  8240.  
  8241.  
  8242.  
  8243.   10.2.2 Turtle.
  8244.  
  8245.   This module  extends the  Graphics module with relative graphics routines
  8246.   (Turtle graphics). The modulee is written in Comal and uses all the routines
  8247.   in the Graphics module.
  8248.  
  8249.   The command  graphicscreen executes an implicit window(-160,160,-100,100)
  8250.   and draws a turtle (a small triangle) in the mittle of the window.
  8251.  
  8252.   All procedures and functions in the Graphics module are accessible from the
  8253.   Turtle module and besides the following routines are supplied:
  8254.  
  8255.  
  8256.     PROC arcl(radius,arc_angle)
  8257.  
  8258.       The procedure  causes an arc to be drawn to the left with the parame-
  8259.       ter radius as the radius of curvature and subtending an angle arc_angle
  8260.       degrees. The starting point is the current position and the starting di-
  8261.       rection is the current direction.
  8262.  
  8263.       Both the current pen position and the current direction is changed.
  8264.  
  8265.  
  8266.                                          145
  8267.  
  8268.  
  8269.  
  8270.  
  8271.  
  8272.       Exampel:
  8273.  
  8274.         arcl(10,90)
  8275.  
  8276.  
  8277.     PROC arcr(radius,right_arc)
  8278.  
  8279.       The procedure causes an arc to be drawn to the  right with  the para-
  8280.       meter  radius  as  the  radius  of  curvature and subtending an angle
  8281.       arc_angle degrees. The starting point is the current position and the
  8282.       starting direction is the current direction.
  8283.  
  8284.       Both the current pen position and the current direction is changed.
  8285.  
  8286.  
  8287.     PROC back(x)
  8288.  
  8289.       The procedure  moves the pen x units backwards in the current drawing
  8290.       direction.
  8291.  
  8292.       The current pen position is changed.
  8293.  
  8294.  
  8295.     PROC forward(x)
  8296.  
  8297.       The procedure moves the pen x  units forward  in the  current drawing
  8298.       direction.
  8299.  
  8300.       The current pen position is changed.
  8301.  
  8302.  
  8303.     FUNC heading
  8304.  
  8305.       The function  returns the value of the current drawing direction. The
  8306.       direction is indicated in degrees with 0 vertically upward and positive
  8307.       to the left.
  8308.     
  8309.  
  8310.     PROC hideturtle
  8311.  
  8312.       The procedure  causes the  drawing pen (the turtle) to disappear from
  8313.       view in the window.
  8314.  
  8315.  
  8316.     PROC home
  8317.  
  8318.       The procedure causes the drawing pen (the turtle) to return to position
  8319.       (0,0) and with drawing direction upward.
  8320.  
  8321.  
  8322.  
  8323.                                          146
  8324.  
  8325.  
  8326.  
  8327.  
  8328.  
  8329.     FUNC inq(no)
  8330.  
  8331.       The function inq returns certain of the internal variable of the gra-
  8332.       phics system. The parameter no must be an integral number in the ran-
  8333.       ge 0-33. The meaning of the returned value can be found in the follo-
  8334.       wing table:
  8335.  
  8336.       number    information about     range     Affected by
  8337.         0       graphics mode         0/1       graphicscreen
  8338.         1
  8339.         2       text background       0-        textbackground
  8340.         3       text color            0-        pencolor
  8341.         4
  8342.         5       graphics backgruond   0-        background
  8343.         6       pen color             0-        pencolor
  8344.         7       graphics text width   8/10      textstyle
  8345.         8       graphics text height  8/10      textstyle
  8346.         9       gr. text direction    0         (dir. cannot be changed)
  8347.        10       graphics text mode    0/1       textstyle
  8348.        11       dr. pen visible       0/1       hideturtle/showturtle
  8349.        12       pen inside dr. frame  0/1       most drawing procs
  8350.        13                             1
  8351.        14                             0
  8352.        15       wrapping active       0         (wrap not implemented)
  8353.        16       pen down              0/1       penup/pendown
  8354.        17       x-position            0-width   most drawing procs
  8355.        18       y-position            0-height  most drawing procs
  8356.        19       viewport xmin         0-width   viewport
  8357.        20       viewport xmax         0-width   viewport
  8358.        21       viewport ymin         0-height  viewport
  8359.        22       viewport ymax         0-height  viewport
  8360.        23       vindow xmin           real no.  window
  8361.        24       vindow xmax           real no.  window
  8362.        25       vindow ymin           real no.  window
  8363.        26       vindow ymax           real no.  window
  8364.        27                             1
  8365.        28                             0
  8366.        29       size of pen           0-        turtlesize
  8367.        30       x-ratio               (rem. 1)  window and viewport
  8368.        31       y-ratio               (rem. 2)  window and viewport
  8369.        32                             0
  8370.        33                             0
  8371.  
  8372.       remark 1: (wdxmax-wdxmin)/(vpxmax-vpxmin)
  8373.       remark 2: (wdymax-wdymin)/(vpymax-vpymin)
  8374.  
  8375.  
  8376.  
  8377.  
  8378.  
  8379.  
  8380.                                          147
  8381.  
  8382.  
  8383.  
  8384.  
  8385.  
  8386.     PROC left(angle)
  8387.  
  8388.       The procedure causes the drawing pen  to be  turned angle  degrees to
  8389.       the left in relation to the current drawing direction.
  8390.  
  8391.  
  8392.     PROC pendown
  8393.  
  8394.       The procedure causes the pen to be lowered. This means that the turtle
  8395.       will draw as it is moved, except for the procedures move and moveto.
  8396.  
  8397.  
  8398.     PROC penup
  8399.  
  8400.       The procedure causes the pen to be lifted. After this the pen will not
  8401.       draw when it is moved, except for the procedures draw and drawto.
  8402.  
  8403.  
  8404.     PROC right(angle)
  8405.  
  8406.       The procedure  causes the  drawing pen  to be turned angle degrees to
  8407.       the right in relation to the current drawing direction.
  8408.  
  8409.  
  8410.     PROC setheading(angle)
  8411.  
  8412.       The procedure causes the drawing direction to be set to angle degrees
  8413.       from the home direction (positive to the left).
  8414.  
  8415.  
  8416.     PROC setxy(x,y)
  8417.  
  8418.       The procedure  causes the pen to be moved to the point with coordina-
  8419.       tes (x,y). If the pen is down it acts like drawto, i.e. a line will be
  8420.       drawn. If pen is up it acts as moveto, i.e. no line will be drawn.
  8421.  
  8422.  
  8423.     PROC showturtle
  8424.  
  8425.       The procedure  causes the  drawing pen  (the turtle) to appear in the
  8426.       window.
  8427.  
  8428.  
  8429.     PROC turtlesize(x)
  8430.  
  8431.       The procedure defines the size of the turtle.
  8432.  
  8433.  
  8434.   In the Turtle module the following abbrivations may be used:
  8435.  
  8436.  
  8437.                                          148
  8438.  
  8439.  
  8440.  
  8441.  
  8442.  
  8443.  
  8444.       bk      =   back
  8445.       bg      =   background
  8446.       cs      =   clearscreen
  8447.       fd      =   forward
  8448.       ht      =   hideturtle
  8449.       lt      =   left
  8450.       pc      =   pencolor
  8451.       pd      =   pendown
  8452.       pu      =   penup
  8453.       rt      =   right
  8454.       seth    =   setheading
  8455.       st      =   showturtle
  8456.       textbg  =   textbackground
  8457.  
  8458.  
  8459.   Most programs developped to  be used  with the  Graphics module  will run
  8460.   without changes  with the  Turtle module. In some cases it is necesary to
  8461.   set the coordinate system back to the physical pixel coordinate system by
  8462.   using the line:
  8463.  
  8464.         window(0,width-1,0,height-1)
  8465.  
  8466.  
  8467.   10.3 Catalog.
  8468.  
  8469.   This module  treats a  directory mush like a file. The module exports the
  8470.   following procedures and functions:
  8471.  
  8472.  
  8473.     PROC OpenCatalog(Name$, REF CatId OF ULONG)
  8474.  
  8475.       Opens a volume or directory  for  subsequent  readings.  The returned
  8476.       value in CatId is used as an identifier for the catalog.
  8477.  
  8478.  
  8479.     PROC ReadCatalog(CatId OF ULONG,REF name$,REF filesize OF LONG)
  8480.  
  8481.       Read the next file/subdirectory from the catalog. If filesize=-1 this is a
  8482.       subdirectory otherwise it is the size of the file.
  8483.  
  8484.  
  8485.     PROC CloseCatalog(number OF ULONG)
  8486.  
  8487.       Close a previosly opened catalog.
  8488.  
  8489.  
  8490.     FUNC EOC(number OF ULONG) OF BOOL
  8491.  
  8492.       Returns TRUE (=1) if no more directories. Otherwise FALSE (=0).
  8493.  
  8494.                                          149
  8495.  
  8496.  
  8497.  
  8498.  
  8499.  
  8500.  
  8501.  
  8502.     PROC CloseAllCatalogs
  8503.  
  8504.       Close all catalogs opened by OpenCatalog.
  8505.  
  8506.  
  8507.  
  8508.   10.4 Bob and sprite modules.
  8509.  
  8510.   The three modules SpriteRoutines, SpriteStrucs and GelObject are  used in
  8511.   connection with gels (bobs and sprites). For normal use it is only the last
  8512.   one that has interest.
  8513.  
  8514.   The module  GelObject contains  two object  definitions VSpriteObject and
  8515.   BobObject. The use of these object are best shown by an example.
  8516.  
  8517.   Let first make a (virtual) sprite. This is done by defining an object:
  8518.  
  8519.     STRUC VirtualSprite
  8520.       INHERIT VSpriteObject
  8521.  
  8522.       PROC Create
  8523.         Init
  8524.       ENDPROC Create
  8525.  
  8526.       // Colors
  8527.       DATA $0F00,$00F0,$000F
  8528.  
  8529.       // Sprite data
  8530.       DATA 12                                   // number of lines
  8531.       //   plane 0           plane 1
  8532.       DATA %1111111111111111,%1111111111111111  // 1. line
  8533.       DATA %1111111111111111,%1100000000000011
  8534.       DATA %1111111111111111,%1100000000000011
  8535.       DATA %1111000000001111,%1100111111110011
  8536.       DATA %1111000000001111,%1100111111110011
  8537.       DATA %1111000000001111,%1100110011110011
  8538.       DATA %1111000000001111,%1100110011110011
  8539.       DATA %1111000000001111,%1100111111110011
  8540.       DATA %1111000000001111,%1100111111110011
  8541.       DATA %1111111111111111,%1100000000000011
  8542.       DATA %1111111111111111,%1100000000000011
  8543.       DATA %1111111111111111,%1111111111111111  // 12. line
  8544.     ENDSTRUC VirtualSprite
  8545.  
  8546.  
  8547.   This object inherits the VSpriteObject and it contains a method Create and
  8548.   DATA statements defining the object.
  8549.  
  8550.  
  8551.                                          150
  8552.  
  8553.  
  8554.  
  8555.  
  8556.  
  8557.   To create a sprite with a shape defined by the  DATA statements  you have
  8558.   to execute a DIM statement:
  8559.  
  8560.     DIM MySprite OF VirtualSprite
  8561.  
  8562.   and then call the methods Create and Draw:
  8563.  
  8564.     MySprite.Create
  8565.     MySprite.Draw(50,50)
  8566.  
  8567.   Now you  can see  the sprite  on the  screen. To move the sprite call the
  8568.   method Move (inherited from VSpriteObject), for instance
  8569.  
  8570.     MySprite.Move(10,10)
  8571.  
  8572.  
  8573.   At the end of your program the sprite has to be deleted:
  8574.  
  8575.     MySprite.Delete
  8576.  
  8577.  
  8578.   A bob is made in almost  the same  way. First  you have  to define  a Bob
  8579.   structure:
  8580.  
  8581.  
  8582.     STRUC Bob
  8583.       INHERIT BobObject
  8584.  
  8585.       PROC Create
  8586.         Init
  8587.       ENDPROC Create
  8588.  
  8589.       // Bob data
  8590.       DATA 1,9                 // Words per line and number of lines
  8591.  
  8592.       // Plane 0
  8593.       DATA %0000111111000011   // 1. line
  8594.       DATA %0011111111110011
  8595.       DATA %0011000011000011
  8596.       DATA %0000000000000000
  8597.       DATA %0000000000000000
  8598.       DATA %0000000000000000
  8599.       DATA %1100000000110011
  8600.       DATA %1111111111000000
  8601.       DATA %0011111100000011   // 9. line
  8602.  
  8603.       // Plane 1
  8604.       DATA %0000000000000000   // 1. line
  8605.       DATA %0000000000000000
  8606.       DATA %0000000000000000
  8607.  
  8608.                                          151
  8609.  
  8610.  
  8611.  
  8612.  
  8613.  
  8614.       DATA %0011110000000011
  8615.       DATA %0011111111000011
  8616.       DATA %0000001111000011
  8617.       DATA %1100000000110011
  8618.       DATA %1111111111000000
  8619.       DATA %0011111100000011   // 9. line
  8620.     ENDSTRUC Bob
  8621.  
  8622.  
  8623.   and execute a DIM statement:
  8624.  
  8625.     DIM MyBob OF Bob
  8626.  
  8627.   The rest of the program is made in the same way as for virtual sprites.
  8628.  
  8629.   You can  have as  many virtual sprite and bobs as you want on the screen.
  8630.   They are all made in the same way.  Only the  DATA statement  may be dif-
  8631.   ferent.
  8632.  
  8633.  
  8634.   10.5 Memory.
  8635.  
  8636.   This module is used to allocate memory from the Amiga's free memory pool.
  8637.  
  8638.   The following routines are exported:
  8639.  
  8640.  
  8641.     FUNC malloc(BlockSize OF ULONG,MemType OF ULONG) OF ULONG
  8642.  
  8643.       Allocate  a  memory  block  of  size  BlockSize  and  of type MemType
  8644.       (MEMF_PUBLIC, MEMF_CLEAR, MEMF_CHIP or MEMF_FAST).
  8645.  
  8646.       The function returns the address of  the block  or zero  if the block
  8647.       could not be allocated.
  8648.  
  8649.  
  8650.     PROC mfree(MemAdr OF ULONG)
  8651.  
  8652.       Free a memory block previosly allocated by malloc
  8653.  
  8654.  
  8655.     PROC mfreeall
  8656.  
  8657.       Free all memory blocks previosly allocated by malloc
  8658.  
  8659.  
  8660.   The module contains a signal routine that calls mfreeall if the variables are
  8661.   cleared.
  8662.  
  8663.  
  8664.  
  8665.                                          152
  8666.  
  8667.  
  8668.  
  8669.  
  8670.  
  8671.  
  8672.   10.6 CodeManInclude and InterpreterInclude.
  8673.  
  8674.   These modules contains definitions to be used to access Comal.CodeMan and
  8675.   Comal.Interpreter (see section V.2).
  8676.  
  8677.  
  8678.  
  8679.   10.7 StartProgram.
  8680.  
  8681.   This module exports one procedure:
  8682.  
  8683.  
  8684.     PROC StartProgram(ProgramName$)
  8685.  
  8686.       Start a Comal program as a seperate process that will terminate itself.
  8687.       The parameter must be the full path of the program that must  be sto-
  8688.       red as a code file.
  8689.  
  8690.  
  8691.   10.9 Timer.
  8692.  
  8693.   This module exports the following procedures:
  8694.  
  8695.  
  8696.     PROC TimerEvent(TimeInterval,EventProc)
  8697.  
  8698.       Start the timer. The timer runs for the specified time interval (in se-
  8699.       conds) and then you procedure EventProc is called. The event procedure
  8700.       is a procedure without parameters.
  8701.  
  8702.  
  8703.     PROC AbortTimer(EventProc)
  8704.  
  8705.       Abort a time event before timeout.
  8706.  
  8707.  
  8708.   The timer  can be used to make periodic interrupts (see section 7.5). The
  8709.   timer interrupts the program at priority 20.
  8710.  
  8711.  
  8712.   10.10 SerialComm.
  8713.  
  8714.   This module is a serial communication module. The following procedures and
  8715.   functions are exported:
  8716.  
  8717.     FUNC chars_in_buff(direction OF BYTE) OF SHORT
  8718.  
  8719.       This function  returns TRUE  if there are chracters in the IO buffer.
  8720.       Otherwise it returns FALSE.
  8721.  
  8722.                                          153
  8723.  
  8724.  
  8725.  
  8726.  
  8727.  
  8728.  
  8729.       If direction is 0 the input buffer is tested. Otherwise it is the output
  8730.       buffer (for  the time  being there is no output buffer and the return
  8731.       value with direction<>0 will always be FALSE).
  8732.  
  8733.  
  8734.     PROC clear_buff(direction OF BYTE)
  8735.  
  8736.       Clear the IO buffer. If direction is 0 the input buffer is tested. Other-
  8737.       wise it is the output buffer.
  8738.  
  8739.  
  8740.     PROC ClearTermArray
  8741.  
  8742.       Remove all break characters set by SetTermArray.
  8743.  
  8744.  
  8745.     PROC CloseSerial
  8746.  
  8747.       Close the serial device and make it available for other tasks.
  8748.  
  8749.  
  8750.     FUNC OpenSerial OF BOOL
  8751.  
  8752.       Open serial  device. If success the value TRUE is returned. Otherwise
  8753.       FALSE is returned.
  8754.  
  8755.  
  8756.     PROC receive(REF Data$,MaxChars OF LONG,MaxWait)
  8757.  
  8758.       Read MaxChars characters into th string Data$. The procedure will re-
  8759.       turn when all characters are received or MaxWait secs has elapsed.
  8760.  
  8761.  
  8762.     PROC send(Data$)
  8763.  
  8764.       Send the string Data$.
  8765.  
  8766.  
  8767.     PROC set_mode(baud OF LONG,parity$,Len OF UBYTE,StopBits OF BYTE)
  8768.  
  8769.       Set communication parameters. The parameters are:
  8770.  
  8771.         baud:     The baud rate.
  8772.         parity$:  "N" = no parity
  8773.                   "E" = even parity
  8774.                   "O" = odd parity
  8775.         Len:      The number of bits in a word (6,7 or 8).
  8776.         StopBits: The number of stop bits (1 or 2).
  8777.  
  8778.  
  8779.                                          154
  8780.  
  8781.  
  8782.  
  8783.  
  8784.  
  8785.  
  8786.     PROC SetTermArray(Arr OF TermArray)
  8787.  
  8788.       Set termination characters. The type TermArray is defined in the modu-
  8789.       le as
  8790.  
  8791.         TYPE TermArray=ARRAY(0..7) OF UBYTE
  8792.  
  8793.       The actual parameter Arr should be filled with characters that  is to
  8794.       break the reading. All 8 characters must be set in non increasing order.
  8795.       If less than 8 break characters is to be used (this is normal) fill the
  8796.       end of the array with the lowest value.
  8797.  
  8798.       Example:
  8799.  
  8800.         DIM Array OF TermArray
  8801.  
  8802.           :
  8803.  
  8804.         Array():=$03    // ^C
  8805.         Array(0):=$1A   // ^Z
  8806.         Array(1):=$04   // ^D
  8807.  
  8808.         SetTermArray(Array())
  8809.  
  8810.           :
  8811.  
  8812.  
  8813.   10.11 Operating system modules.
  8814.  
  8815.   A number  of modules are to be used to access the operating system routi-
  8816.   nes. These routines are devided into two groups:
  8817.  
  8818.  
  8819.     - Library interfaces for the system routines themself. These modules are
  8820.       mashine coded modules.
  8821.  
  8822.     - Definitions necessary to call the system routines.
  8823.  
  8824.  
  8825.   10.11.1 Library interface routines.
  8826.  
  8827.   These modules are:
  8828.  
  8829.         AslLibrary
  8830.         DosLibrary
  8831.         ExecLibrary
  8832.         GadToolsLibrary
  8833.         GraphicsLibrary
  8834.         IntuitionLibrary
  8835.  
  8836.                                          155
  8837.  
  8838.  
  8839.  
  8840.  
  8841.  
  8842.  
  8843.  
  8844.   The modules contains interfaces for all the routines in the corresponding
  8845.   libraries. The names and the calling conventions are exactly the same as is
  8846.   used in a C program.
  8847.  
  8848.   Example: This program opens a window and closes it again
  8849.  
  8850.     USE System    
  8851.     USE IntuitionWindow    
  8852.     USE IntuitionLibrary    
  8853.  
  8854.     DIM NewWindow OF NewWindow
  8855.     DIM Window OF POINTER TO Window    
  8856.  
  8857.     NewWindow.LeftEdge:=50
  8858.     NewWindow.TopEdge:=30
  8859.     NewWindow.Width:=300
  8860.     NewWindow.Height:=100
  8861.     NewWindow.BlockPen:=1
  8862.     NewWindow.Title:=ADR("Window demo")
  8863.     NewWindow.Screen:=ComalStruc@.IO_Screen
  8864.     NewWindow.Flags:=WINDOWDEPTH BITOR WINDOWDRAG
  8865.     NewWindow.Type:=CUSTOMSCREEN
  8866.  
  8867.     Window:=OpenWindow(ADR(NewWindow))      
  8868.     WAIT 3
  8869.     CloseWindow(Window)        
  8870.  
  8871.  
  8872.   The library interface modules will not be described in detail here. Consult a
  8873.   description of the Amiga OS system routines.
  8874.  
  8875.  
  8876.  
  8877.   10.11.2 Definitions for use in the library modules.
  8878.  
  8879.   The definitions to be used in connection with calls to library routines are
  8880.   found in the following modules:
  8881.  
  8882.  
  8883.     AslInclude
  8884.  
  8885.       Structures:
  8886.         STRUC FileRequester
  8887.         STRUC FontRequester
  8888.  
  8889.       Types:
  8890.         TYPE FileReqPtr=POINTER TO FileRequester
  8891.  
  8892.  
  8893.                                          156
  8894.  
  8895.  
  8896.  
  8897.  
  8898.  
  8899.       Constants:
  8900.         ASL_FuncFlag file requester tag values (FILF_DOWILDFUNC ..)
  8901.         ASL_ExtFlags1 file requester tag values (FILF1_NOFILES ..)
  8902.         ASL_FuncFlag font requester tag values  (FONF_FRONTCOLOR ...)
  8903.         requester types (ASL_FileRequest and ASL_FontRequest)
  8904.         tags for AllocAslRequestA and AslRequestA (ASL_Hail ...)
  8905.  
  8906.  
  8907.     DosAslInclude
  8908.  
  8909.       Structures:
  8910.         STRUC DateStamp
  8911.         STRUC FileInfoBlock
  8912.         STRUC AChain
  8913.         STRUC AnchorPath
  8914.  
  8915.       Types:
  8916.         TYPE FileInfoPtr=POINTER TO FileInfoBlock
  8917.         TYPE AnchorPathPtr=POINTER TO AnchorPath
  8918.  
  8919.  
  8920.     ExecLists
  8921.  
  8922.       Structures:
  8923.         STRUC Node
  8924.         STRUC List
  8925.           FUNC New CONSTRUCTOR
  8926.             Initializes the list.
  8927.  
  8928.       Constants:
  8929.         Node types (NT_TASK, NT_MESSAGE ...)
  8930.  
  8931.  
  8932.     GadToolsInclude
  8933.  
  8934.       Structures:
  8935.         STRUC StringInfo
  8936.         STRUC Gadget
  8937.         STRUC NewGadget
  8938.         STRUC NewMenu
  8939.  
  8940.       Constants:
  8941.         Gadget types (GENERIC_KIND, BUTTON_KIND ...)
  8942.         IDCMP flags (ARROWIDCMP, BUTTONIDCMP ...)
  8943.         spacing constants (INTERWIDTH and INTERHEIGHT)
  8944.         NewGadget flags (NG_HIGHLABEL, PLACETEXT_LEFT ...)
  8945.         NewMenu types (NM_TITLE, NMITEM ...)
  8946.         return codes (GTMENU_TRIMMED ...)
  8947.         tags for tool kit functions (GTVI_NewWindow, GTVI_NWTags ...)
  8948.  
  8949.  
  8950.                                          157
  8951.  
  8952.  
  8953.  
  8954.  
  8955.  
  8956.  
  8957.     Gfx
  8958.  
  8959.       Functions and procedures:
  8960.         FUNC RASSIZE(w,h)     (in fact a macro in C include files)
  8961.  
  8962.       Structures:
  8963.         STRUC RectAngle
  8964.         STRUC BitMap
  8965.  
  8966.  
  8967.     IDCMP
  8968.  
  8969.       Structures:
  8970.         STRUC IntuiMessage    (inherits Message from PortObjects)
  8971.  
  8972.       Constants:
  8973.         IDCMP classes (SIZEVERYFY, NEWSIZE ...)
  8974.         Mouse codes and key qualifiers (SELECTUP, ALTLEFT, ...)
  8975.  
  8976.  
  8977.     IntuiText
  8978.  
  8979.       Structures:
  8980.         STRUC IntuiText
  8981.         STRUC TextAttr
  8982.  
  8983.  
  8984.       Constants:
  8985.         draw modes (JAM1, JAM2, XOR)
  8986.  
  8987.  
  8988.     IoObjects
  8989.  
  8990.       Structures:
  8991.  
  8992.         STRUC IoRequest
  8993.           INHERIT Message
  8994.           PROC Init Constructor
  8995.             Initializes the length of the message.
  8996.           PROC Do
  8997.             Calls DoIO  in the  ExecLibrary with a pointer to the object as
  8998.             parameter.
  8999.           PROC Send
  9000.             Calls SendIO in the ExecLibrary with a pointer to the object as
  9001.             parameter.
  9002.           PROC Abort
  9003.             Calls AbortIO in the ExecLibrary with a pointer to the object as
  9004.             parameter.
  9005.  
  9006.  
  9007.                                          158
  9008.  
  9009.  
  9010.  
  9011.  
  9012.  
  9013.         STRUC IoStdReq
  9014.           INHERIT IoRequest
  9015.           PROC Init Constructor
  9016.             Initializes the length of the message.
  9017.  
  9018.  
  9019.     Layers
  9020.  
  9021.       Structures:
  9022.         STRUC Layer_Info
  9023.  
  9024.       Constants:
  9025.         Layer types etc. (LAYERSIMPLE, LAYERSMART ...)
  9026.  
  9027.  
  9028.     MenuStrucs
  9029.  
  9030.       Structures:
  9031.         STRUC Menu
  9032.         STRUC MenuItem
  9033.  
  9034.       Constans:
  9035.         menu and item flags (MENUENABLED, CHECKIT, ITEMTEXT ...)
  9036.         MENUNULL
  9037.  
  9038.  
  9039.     PortObjects
  9040.  
  9041.       Structures:
  9042.         STRUC MsgPort
  9043.           FUNC Init CONSTRUCTOR
  9044.             Makes the necessary initialization for a private port (allocates a
  9045.             signal bit etc.).
  9046.           PROC Delete DESTRUCTOR
  9047.             Removes the  port from  the list of public ports (if the method
  9048.             Add has been called) and deallocates the signal.
  9049.           PROC Add(REF Name$,Priority OF BYTE)
  9050.             Adds the port to the list of public ports.
  9051.           PROC Wait
  9052.             Wait for a message to arrive. It is possible to break the program
  9053.             during the wait.
  9054.           FUNC Get
  9055.             The ExecLibrary function GetMsg is called with a pointer to the
  9056.             port as parameter.
  9057.           PROC Put(REF Msg OF Message)
  9058.             The ExecLibrary procedure PutMsg  is called  with a  pointer to
  9059.             the port and the message as parameter.
  9060.  
  9061.         STRUC Message
  9062.           FUNC Init CONSTRUCTOR
  9063.  
  9064.                                          159
  9065.  
  9066.  
  9067.  
  9068.  
  9069.  
  9070.             Initializes the message (but no reply port is created!!).
  9071.           PROC Wait
  9072.             Waits for the message to be replied and remove the message from
  9073.             the reply port.
  9074.           PROC Reply
  9075.             Replies the message.
  9076.  
  9077.  
  9078.         Before you can use  the message  you will  normally have  to make a
  9079.         reply port  and put  an address  of this port into the mn_ReplyPort
  9080.         field.
  9081.  
  9082.  
  9083.     RastPort
  9084.  
  9085.       Structures:
  9086.         STRUC AreaInfo
  9087.         STRUC TmpRas
  9088.         STRUC RastPort
  9089.  
  9090.  
  9091.       Constants:
  9092.         drawing modes (JAM1, JAM2, COMPLEMENT, INVERSEVID)
  9093.         bits for RastPort flags (FRST_DOT, ONE_DOT, DBUFFER)
  9094.  
  9095.  
  9096.     TagItem
  9097.  
  9098.       Structures:
  9099.         STRUC TagItem
  9100.  
  9101.  
  9102.       Constants:
  9103.         system tags (TAG_DONE, TAG_END, .. , TAG_USER)
  9104.         TAGFILTER_AND, TAGFILTER_NOT
  9105.  
  9106.  
  9107.     View
  9108.  
  9109.       Structures:
  9110.         STRUC ColorMap
  9111.         STRUC ViewPort
  9112.         STRUC View
  9113.         STRUC RasInfo
  9114.  
  9115.       Constants:
  9116.         view modes (PFBA, DUALPF, HIRES, ...)
  9117.  
  9118.  
  9119.  
  9120.  
  9121.                                          160
  9122.  
  9123.  
  9124.  
  9125.  
  9126.  
  9127.     IntuitionWindow
  9128.  
  9129.       Structures:
  9130.         STRUC NewWindow
  9131.         STRUC Window
  9132.  
  9133.       Constants:
  9134.         flag bits set by Intuition (SCREENTYPE, WBENCHSCREEN, ...)
  9135.         window flags (WINDOWSIZING, WINDOWDRAG, ...)
  9136.  
  9137.  
  9138.     IntuitionScreen
  9139.  
  9140.       Structures:
  9141.         STRUC NewScreen
  9142.         STRUC Screen
  9143.  
  9144.  
  9145.  
  9146.   11 The Comal Intuition Tools (CIT).
  9147.  
  9148.  
  9149.     NOTE! CIT requires Workbench 2.04 or higher.
  9150.  
  9151.  
  9152.   The Comal Intuition Tool (short CIT) is a set of modules that are used to
  9153.   build various Intuition items: screens, windows, gadgets etc.
  9154.  
  9155.   Normally the creation of Intuition items involves filling out special struc-
  9156.   tures with special values. If the item is used to act on  response from a
  9157.   user (such as gadgets or menus) you also have to work with message ports,
  9158.   signals and messages. And you must evaluate each message to find out what
  9159.   to do.
  9160.  
  9161.   By using CIT it is much easier. All the necessary structures are filled auto-
  9162.   matically with standard values that  can  be  changed  by  calling object
  9163.   methods. You  don't have  to know  anything about ports, signals and mes-
  9164.   sages and the evaluation of a user action is done by the objects.
  9165.  
  9166.  
  9167.  
  9168.   11.1 General description of CIT.
  9169.  
  9170.   In CIT all Intuition items are treated as Objects. For  example, a button
  9171.   gadget is  an object  that can  be placed  in a window and a window is an
  9172.   object that can be placed in a screen.
  9173.  
  9174.   Certain objects have similar characteristics and  can be  classified into
  9175.   groups called classes. For instance, menus and gadgets are similiar in that
  9176.   they are placed in a window. They are classified as WindowClass objects. In
  9177.  
  9178.                                          161
  9179.  
  9180.  
  9181.  
  9182.  
  9183.  
  9184.   the same  way a  check box, a button gadget and a string input gadget are
  9185.   similar. They are classified as members of the class CITGadget (a subclass
  9186.   of the WindowClass).
  9187.  
  9188.   All the  objects are  implemented as  structures. You should think of the
  9189.   objects as physical items. First you have to create it. This is done by exe-
  9190.   cuting a  DIM or  LOCAL statement. Then you will proporly add some attri-
  9191.   butes like a position, a size or even a colour.  This is  done by calling
  9192.   methods in the structure. Finally you will place it somewhere. This is done
  9193.   by calling a method InsObject in the containing object.
  9194.  
  9195.   As can be seen, all objects are placed in other objects. In this way objects
  9196.   form an object hierachy as shown below (the boxes containing '??' are not
  9197.   defined for the time being):
  9198.  
  9199.                             +---------------+
  9200.                             |               |
  9201.                             | CITWorkbench  |
  9202.                             |               |
  9203.                             +---------------+
  9204.                               ^     ^     ^
  9205.                               |     |     |
  9206.           +-------------------+     |     +------------------+
  9207.           |                         |                        |
  9208.     +------------+           +-------------+          +-------------+
  9209.     |            |           |             |          |             |
  9210.     |   ??       |  ......   |  CITScreen  |  ......  |    ??       |
  9211.     |            |           |             |          |             |
  9212.     +------------+           +-------------+          +-------------+
  9213.                               ^     ^     ^
  9214.                               |     |     |
  9215.           +-------------------+     |     +------------------+
  9216.           |                         |                        |
  9217.     +------------+           +-------------+          +-------------+
  9218.     |            |           |             |          |             |
  9219.     |   ??       |  ......   |  CITWindow  |  ......  |    ??       |
  9220.     |            |           |             |          |             |
  9221.     +------------+           +-------------+          +-------------+
  9222.                               ^  ^  ^  ^  ^
  9223.                               |  |  |  |  |
  9224.                               |  |  |  |  |
  9225.           +-------------------+  |  |  |  +------------------+
  9226.           |                      |  |  |                     |
  9227.           |           +----------+  |  +-------+             |
  9228.           |           |             |          |             |
  9229.     +-----------+     |    +-------------+     |      +-------------+
  9230.     |           |     |    |             |     |      |             |
  9231.     |  CITText  |     |    |  CITGadgets |     |      |   CITMenus  |
  9232.     |           |     |    |             |     |      |             |
  9233.     +-----------+     |    +-------------+     |      +-------------+
  9234.  
  9235.                                          162
  9236.  
  9237.  
  9238.  
  9239.  
  9240.  
  9241.                       |                        |
  9242.                 +-----------+           +-------------+
  9243.                 |           |           |             |
  9244.           ....  |  CITMouse | ........  | CITRequester| ......
  9245.                 |           |           |             |
  9246.                 +-----------+           +-------------+
  9247.  
  9248.  
  9249.  
  9250.   The use of all these different sorts of objects follow the same scheme:
  9251.  
  9252.   To create an object you have to execute a DIM (or LOCAL) statement like:
  9253.  
  9254.       DIM MyObject OF CITObject
  9255.  
  9256.  
  9257.   Most of the visible objects have a Size method and  a Position  method to
  9258.   set its size and its position:
  9259.  
  9260.       MyObject.Size(Width,Height)
  9261.       MyObject.Position(LeftEdge,TopEdge)
  9262.  
  9263.   and some have a Label method to connect a text to the object:
  9264.  
  9265.       MyObject.Label(SomeText$)
  9266.  
  9267.  
  9268.   These methods  are always  named Size,  Position and Label, but sometimes
  9269.   there are additional parameters. In some of the gadgets, for instance, you
  9270.   have to specify if the text is to be placed inside the object itself or to the
  9271.   left, to the right etc.
  9272.  
  9273.   If the object is to respond to a user action  and you  want immediate re-
  9274.   sponse, you  have to call the method EventHandler with the name of a pro-
  9275.   cedure to be called as the result of the users action:
  9276.  
  9277.       MyObject.EventHandler(MyObjectEvent())
  9278.  
  9279.  
  9280.   The number and types of the parameters in the event  procedure are diffe-
  9281.   rent from object type to object type (in the example we have indicated one
  9282.   parameter).
  9283.  
  9284.   Having set all the attributes you have to insert it in another object. This is
  9285.   done by calling the method InsObject in the container object:
  9286.  
  9287.       Container.InsObject(MyObject,Error)
  9288.  
  9289.  
  9290.   When you are finished using the object you should remove it by calling the
  9291.  
  9292.                                          163
  9293.  
  9294.  
  9295.  
  9296.  
  9297.  
  9298.   method RemObject in the container object:
  9299.  
  9300.       Container.RemObject(MyObject)
  9301.  
  9302.  
  9303.   NOTE: Not all objects can be removed individually.
  9304.  
  9305.   By removing the object MyObject all objects contained in this object will
  9306.   be removed, too.
  9307.  
  9308.   Between the  insertion and  the removal  you will normally be waiting for
  9309.   some termination code to take on a non zero value. This is typically done
  9310.   in a loop like:
  9311.  
  9312.       WHILE NOT Terminate DO WAIT
  9313.  
  9314.  
  9315.   While you are waiting all your event procedures will be called automatically.
  9316.  
  9317.   In the following sections you will find a complete description of all the CIT
  9318.   objects.
  9319.  
  9320.  
  9321.   11.2 Simple CIT examples.
  9322.  
  9323.   As a simple example of the use of CIT let's make a  window with  a string
  9324.   input gadget and a button gadget to terminate the input.
  9325.  
  9326.   First we have to load the modules we are using:
  9327.  
  9328.     USE CITScreen
  9329.     USE CITWindow
  9330.     USE CITGadgets
  9331.  
  9332.   and then we will create our window:
  9333.  
  9334.     DIM DemoWindow OF CITWindow
  9335.  
  9336.   give it the right size, place it on the correct position in the containing
  9337.   screen and make it active when it opens:
  9338.  
  9339.     DemoWindow.Size(500,100)
  9340.     DemoWindow.Position(60,50)
  9341.     DemoWindow.Activate
  9342.  
  9343.  
  9344.   We want  to place  the window  in the  ComalScreen which  is a predefined
  9345.   screen found in the module CITScreen:
  9346.  
  9347.     ComalScreen.InsObject(DemoWindow,Error)
  9348.  
  9349.                                          164
  9350.  
  9351.  
  9352.  
  9353.  
  9354.  
  9355.  
  9356.  
  9357.   Any error code is returned in the variable Error. We have to test this va-
  9358.   riable before we proceed:
  9359.  
  9360.     IF Error THEN
  9361.       STOP "Could not create window"
  9362.     ENDIF
  9363.  
  9364.  
  9365.   The string input gadget is created, sized and positioned in the same way:
  9366.  
  9367.     DIM NameInput OF StringGadget
  9368.     NameInput.Size(300,15)
  9369.     NameInput.Position(160,10)
  9370.  
  9371.  
  9372.   We want a text to the left of the gadget:
  9373.  
  9374.     NameInput.Label("Enter your name: ",LEFT)
  9375.  
  9376.  
  9377.   This input gadget is placed in the window in exactly the same  way as the
  9378.   window was placed in the screen:
  9379.  
  9380.     DemoWindow.InsObject(NameInput,Error)
  9381.  
  9382.  
  9383.   And now the button gadget:
  9384.  
  9385.     DIM OkButton OF ButtonGadget
  9386.     OkButton.Size(40,15)
  9387.     OkButton.Position(10,-(6+15))
  9388.     OkButton.Label("Ok",INSIDE)           // Place text inside the gadget
  9389.     DemoWindow.InsObject(OkButton,Error)
  9390.  
  9391.  
  9392.   Note that the y-coordinate of the position is negative. Then the gadget is
  9393.   positioned relative to the buttom border of the window.
  9394.  
  9395.   The variable Error is only changed if an error occurs. Let's test it now:
  9396.  
  9397.     IF Error THEN
  9398.       STOP "Could not create one or more gadgets"
  9399.     ENDIF
  9400.  
  9401.  
  9402.   Now we will sleep until the Ok button is pressed:
  9403.  
  9404.     WHILE NOT OkButton.Pressed DO WAIT
  9405.  
  9406.                                          165
  9407.  
  9408.  
  9409.  
  9410.  
  9411.  
  9412.  
  9413.  
  9414.   The text typed into the input gadget is found in a field by name Value$ in
  9415.   the OkButton structure:
  9416.  
  9417.     PRINT "Your name is: ",NameInput.Value$
  9418.  
  9419.  
  9420.   As the  final task we have to close the window (and all items inserted in
  9421.   the window):
  9422.  
  9423.     ComalScreen.RemObject(DemoWindow)
  9424.  
  9425.  
  9426.   The complete program looks like:
  9427.  
  9428.     USE CITScreen
  9429.     USE CITWindow
  9430.     USE CITGadgets
  9431.  
  9432.     DIM DemoWindow OF CITWindow
  9433.     DemoWindow.Size(500,100)
  9434.     DemoWindow.Position(60,50)
  9435.     DemoWindow.Activate
  9436.     ComalScreen.InsObject(DemoWindow,Error)
  9437.     IF Error THEN
  9438.       STOP "Could not create window"
  9439.     ENDIF
  9440.  
  9441.     DIM NameInput OF StringGadget
  9442.     NameInput.Size(300,15)
  9443.     NameInput.Position(160,10)
  9444.     NameInput.Label("Enter your name: ",LEFT)
  9445.     DemoWindow.InsObject(NameInput,Error)
  9446.  
  9447.     DIM OkButton OF ButtonGadget
  9448.     OkButton.Size(40,15)
  9449.     OkButton.Position(10,-(6+15))
  9450.     OkButton.Label("Ok",INSIDE)
  9451.     DemoWindow.InsObject(OkButton,Error)
  9452.  
  9453.     IF Error THEN
  9454.       STOP "Could not create one or more gadgets"
  9455.     ENDIF
  9456.  
  9457.     WHILE NOT OkButton.Pressed DO WAIT
  9458.  
  9459.     PRINT "Your name is: ",NameInput.Value$
  9460.  
  9461.     ComalScreen.RemObject(DemoWindow)
  9462.  
  9463.                                          166
  9464.  
  9465.  
  9466.  
  9467.  
  9468.  
  9469.  
  9470.  
  9471.   In our next example  we will  add a  Cancel button  to the  window and an
  9472.   event procedure to each of the button gadgets. These procedures are called
  9473.   each time the respective  buttons are  pressed. The  OkEvent procedure is
  9474.   added in this way:
  9475.  
  9476.     OkButton.EventHandler(OkEvent())
  9477.  
  9478.       :
  9479.  
  9480.     PROC OkEvent(Id OF USHORT)
  9481.       Terminate:=1
  9482.     ENDPROC OkEvent
  9483.  
  9484.  
  9485.   The Cancel button (including the event procedure) is made in this way:
  9486.  
  9487.     DIM CancelButton OF ButtonGadget
  9488.     CancelButton.Size(60,15)
  9489.     CancelButton.Position(-(10+60),-(6+15))
  9490.     CancelButton.Label("Cancel",INSIDE)
  9491.     CancelButton.EventHandler(CancelEvent())
  9492.     DemoWindow.InsObject(CancelButton,Error)
  9493.     PROC CancelEvent(Id OF USHORT)
  9494.       Terminate:=2
  9495.     ENDPROC CancelEvent
  9496.  
  9497.  
  9498.   Having done  this and having testet for errors we will go to sleep. While
  9499.   sleeping the system will call the event procedures for you:
  9500.  
  9501.     WHILE NOT Terminate DO WAIT
  9502.  
  9503.  
  9504.   The complete program looks like (note that the variable Terminate  has to
  9505.   be dimensioned before you go to sleep):
  9506.  
  9507.     USE CITScreen
  9508.     USE CITWindow
  9509.     USE CITGadgets
  9510.  
  9511.     DIM Terminate OF SHORT
  9512.  
  9513.     DIM DemoWindow OF CITWindow
  9514.     DemoWindow.Size(500,100)
  9515.     DemoWindow.Position(60,50)
  9516.     DemoWindow.Activate
  9517.     ComalScreen.InsObject(DemoWindow,Error)
  9518.     IF Error THEN
  9519.  
  9520.                                          167
  9521.  
  9522.  
  9523.  
  9524.  
  9525.  
  9526.       STOP "Could not create window"
  9527.     ENDIF
  9528.  
  9529.     DIM NameInput OF StringGadget
  9530.     NameInput.Size(300,15)
  9531.     NameInput.Position(160,10)
  9532.     NameInput.Label("Enter your name: ",LEFT)
  9533.     DemoWindow.InsObject(NameInput,Error)
  9534.  
  9535.     DIM OkButton OF ButtonGadget
  9536.     OkButtonSize(60,15)
  9537.     OkButtonPosition(10,-(6+15))
  9538.     OkButtonLabel("Ok",INSIDE)
  9539.     OkButtonEventHandler(OkEvent())
  9540.     DemoWindow.InsObject(OkButton,Error)
  9541.     PROC OkEvent(id OF USHORT)
  9542.       Terminate:=1
  9543.     ENDPROC OkEvent
  9544.  
  9545.     DIM CancelButton OF ButtonGadget
  9546.     CancelButton.Size(60,15)
  9547.     CancelButton.Position(-(10+60),-(6+15))
  9548.     CancelButton.Label("Cancel",INSIDE)
  9549.     CancelButton.EventHandler(CancelEvent())
  9550.     DemoWindow.InsObject(CancelButton,Error)
  9551.     PROC CancelEvent(id OF USHORT)
  9552.       Terminate:=2
  9553.     ENDPROC CancelEvent
  9554.  
  9555.     IF Error THEN
  9556.       STOP "Could not create one or more gadgets"
  9557.     ENDIF
  9558.  
  9559.     WHILE NOT Terminate DO WAIT
  9560.  
  9561.     CASE Terminate OF
  9562.     WHEN 1
  9563.       PRINT "Hello ",NameInput.Value$,". Welcome to the world of CIT"
  9564.     WHEN 2
  9565.       PRINT "You don't know your name!?"
  9566.     ENDCASE
  9567.  
  9568.     ComalScreen.RemObject(DemoWindow)
  9569.  
  9570.  
  9571.   In the tutorial other examples are shown (chapter II.8-9).
  9572.  
  9573.  
  9574.  
  9575.  
  9576.  
  9577.                                          168
  9578.  
  9579.  
  9580.  
  9581.  
  9582.  
  9583.   11.3 CIT reference.
  9584.  
  9585.   In the following subsections you will find a complete description of all the
  9586.   modules containing CIT objects, the object methods and the attributes that
  9587.   can be set in the objects.
  9588.  
  9589.  
  9590.   11.3.1 CITWorkbench.
  9591.  
  9592.   The  CITWorkbench  module  containns  the  basic object CITWorkbench. You
  9593.   cannot create a CITWorkbench object yourself. It is already created in the
  9594.   module.
  9595.  
  9596.   The following methods in CITWorkbench can be used:
  9597.  
  9598.  
  9599.     PROC InsObject(REF WBObject OF WorkbenchClass,REF Error OF SHORT)
  9600.  
  9601.       An object  of the class WorkbenchClass is placed on the CITWorkbench.
  9602.       For the time being  CITScreen is  the only  member of  the Workbench-
  9603.       Class.
  9604.  
  9605.  
  9606.     PROC RemObject(REF WBObject OF WorkbenchClass)
  9607.  
  9608.       Remove an object from the the CITWorkbench.
  9609.  
  9610.  
  9611.   If variables in the program are cleared all objects inserted in CITWorkbench
  9612.   are automatically removed.
  9613.  
  9614.  
  9615.   11.3.2 CITScreen.
  9616.  
  9617.   The object CITScreen found in  the  CITScreen  module  is  member  of the
  9618.   WorkbenchClass (the only member for the time being).
  9619.  
  9620.   A CITScreen  has to be created in a DIM (or LOCAL) statement and inserted
  9621.   in CITWorkbench. The screen will be a high resolution screen  (640 pixels
  9622.   horizontal).
  9623.  
  9624.   Example: 
  9625.  
  9626.     DIM MyScreen OF CITScreen
  9627.     MyScreen.Label("My Own Screen")
  9628.     MyScreen.Depth(3)
  9629.     CITWorkbench.InsObject(MyScreen,Error)
  9630.  
  9631.  
  9632.   The following methods in CITScreen can be used:
  9633.  
  9634.                                          169
  9635.  
  9636.  
  9637.  
  9638.  
  9639.  
  9640.  
  9641.  
  9642.     PROC InsObject(REF ScrObject OF ScreenClass,REF Error OF SHORT)
  9643.  
  9644.       An object of the class ScreenClass is placed in a CITScreen object.
  9645.  
  9646.       For the time being CITWindow is the only member of the ScreenClass.
  9647.  
  9648.     
  9649.     PROC RemObject(REF ScrObject OF ScreenClass)
  9650.  
  9651.       Remove a ScreenClass object from the CITScreen
  9652.  
  9653.  
  9654.     PROC Label(t$)
  9655.  
  9656.       Place a text in the drag bar of the screen. This method may be called
  9657.       only before the screen has been inserted in CITWorkbench.
  9658.  
  9659.     
  9660.     PROC Depth(d OF SHORT)
  9661.  
  9662.       Set the depth (the number of colors) of  the screen.  This method may
  9663.       be called only before the screen has been inserted in CITWorkbench.
  9664.  
  9665.  
  9666.     PROC Lores
  9667.  
  9668.       Make the screen a low resolution screen (the horizontal resolution is
  9669.       halfed).  This method may be called only  before the  screen has been
  9670.       inserted in CITWorkbench. 
  9671.  
  9672.  
  9673.     PROC Interlace
  9674.  
  9675.       Make the screen an interlace screen (the vertical resolution is doubled).
  9676.       This method may be called only before the screen has been inserted in
  9677.       CITWorkbench. 
  9678.  
  9679.  
  9680.     PROC ToBack
  9681.  
  9682.       Send the  screen behind all other screens.  This method may be called
  9683.       only after the screen has been inserted in CITWorkbench.
  9684.  
  9685.  
  9686.     PROC ToFront
  9687.  
  9688.       Bring the screen in front of all other screens. This method may be cal-
  9689.       led only after the screen has been inserted in CITWorkbench.
  9690.  
  9691.                                          170
  9692.  
  9693.  
  9694.  
  9695.  
  9696.  
  9697.  
  9698.  
  9699.     PROC Font(FontName$,FontHeight OF SHORT)
  9700.  
  9701.       Set the default font of this screen. FontName$ is the name of the font
  9702.       (including the '.font' extension) and FontHeight is the desired height of
  9703.       the font.
  9704.  
  9705.       If the  font with  the name  and the specified height cannot be found
  9706.       nothing will happen.
  9707.  
  9708.  
  9709.   Two predefined ready to use screens are exported from the  CITSreen modu-
  9710.   le: ComalScreen  (the screen used by the Comal system ) and WBScreen (the
  9711.   Workbench screen). They are used in  the  same  way  as  other CITScreens
  9712.   (except that they cannot be inserted in or removed from CITWorkbench).
  9713.  
  9714.  
  9715.   11.3.3 CITWindow.
  9716.  
  9717.   In the module CITWindow the object CITWindow is found.
  9718.  
  9719.   CITWindow  is  member  of  the  ScreenClass (the only member for the time
  9720.   being). A CITWindow has to be created in a DIM  (or LOCAL)  statement and
  9721.   inserted in a screen.
  9722.  
  9723.  
  9724.   Example: 
  9725.  
  9726.     DIM DemoWindow OF CITWindow
  9727.     DemoWindow.Size(530,150)
  9728.     ComalScreen.InsObject(DemoWindow,Error)
  9729.  
  9730.  
  9731.   The following methods in CITWindow can be used:
  9732.  
  9733.  
  9734.     PROC InsObject(REF WdObject OF WindowClass,REF Error OF SHORT)
  9735.  
  9736.       An object of the class WindowClass is placed in the CITWindow.
  9737.  
  9738.       All  kinds   of  IDCMP   events  except   MOUSEBUTTON  and  MOUSEMOVE
  9739.       events will be resend to the object as soon as they are recieved by the
  9740.       window.
  9741.  
  9742.     
  9743.     PROC RemObject(REF WdObject OF WindowClass)
  9744.  
  9745.       Remove a WindowClass object from the CITWindow.
  9746.  
  9747.  
  9748.                                          171
  9749.  
  9750.  
  9751.  
  9752.  
  9753.  
  9754.  
  9755.     PROC Position(x OF USHORT,y OF USHORT)
  9756.  
  9757.       Set position of the window. This method may be called both before and
  9758.       after the window has been inserted in a screen.
  9759.  
  9760.  
  9761.     PROC Size(w OF USHORT,h OF USHORT)
  9762.  
  9763.       Set the size of the window. This method may be called both before and
  9764.       after the window has been inserted in a screen.
  9765.  
  9766.  
  9767.     PROC Label(t$)
  9768.  
  9769.       Set the window title. This method may be called both before and after
  9770.       the window has been inserted in a screen.
  9771.  
  9772.  
  9773.     PROC Activate
  9774.  
  9775.       Make window the active.  This method  may be  called both  before and
  9776.       after the window has been inserted in a screen.
  9777.  
  9778.  
  9779.     PROC DepthGadget
  9780.  
  9781.       Make a  depth gadget  in the  upper right  corner of the window. This
  9782.       method may be called only before  the window  has been  inserted in a
  9783.       screen.
  9784.  
  9785.  
  9786.     PROC SizingGadget
  9787.  
  9788.       Make a  sizing gadget  in the  lower right corner of the window. This
  9789.       method may be called only before  the window  has been  inserted in a
  9790.       screen.
  9791.  
  9792.  
  9793.     PROC DragBar
  9794.  
  9795.       Add a  drag bar  to the  window (so  that the  window can be moved by
  9796.       the user). This method may be called only before the  window has been
  9797.       inserted in a screen.
  9798.  
  9799.  
  9800.     PROC NoBorder
  9801.  
  9802.       The window  will be  opened without a border. This method may be cal-
  9803.       led only before the window has been inserted in a screen.
  9804.  
  9805.                                          172
  9806.  
  9807.  
  9808.  
  9809.  
  9810.  
  9811.  
  9812.     PROC InterruptPriority(n BYTE)
  9813.  
  9814.       Set interrupt priority of window interrupts. This method may be called
  9815.       only before the window has been inserted in a screen
  9816.  
  9817.  
  9818.     PROC ToFront
  9819.  
  9820.       Bring the  window in  front of  all other windows on the screen. This
  9821.       method may be called  only after  the window  has been  inserted in a
  9822.       screen.
  9823.  
  9824.  
  9825.     PROC ToBack
  9826.  
  9827.       Bring the  window behind all other windows on the screen. This method
  9828.  
  9829.  
  9830.     PROC CloseGadget
  9831.  
  9832.       Make a  close gadget  in the  upper left  corner of  the window. This
  9833.       method may  be called  only before  the window has been inserted in a
  9834.       screen.
  9835.  
  9836.  
  9837.     FUNC ClosePressed
  9838.  
  9839.       This boolean function returns  TRUE if  the windows  close gadget has
  9840.       been pressed. The status of the gadget will be set to FALSE after the
  9841.       call.
  9842.  
  9843.  
  9844.     PROC CloseEventHandler(p OF CloseEventProc)
  9845.  
  9846.       By calling this method with a procedure p, this procedure will be called
  9847.       immediately if the close gadget is pressed.
  9848.  
  9849.       The parameter p is a procedure without parameters.
  9850.  
  9851.       Example:
  9852.           DemoWindow.CloseEventHandler(CloseEvent)
  9853.  
  9854.             :
  9855.  
  9856.           PROC CloseEvent
  9857.  
  9858.             <do necessary actions>
  9859.  
  9860.           ENDPROC CloseEvent
  9861.  
  9862.                                          173
  9863.  
  9864.  
  9865.  
  9866.  
  9867.  
  9868.  
  9869.  
  9870.     PROC SelectEventHandler(EventProc OF ButtonEventProc)
  9871.  
  9872.       By calling this the method the procedure EventProc will be called when
  9873.       the left mouse button (select button) is pressed.
  9874.  
  9875.       EventProc is an event procedure of the form:
  9876.  
  9877.         PROC Button(Down OF BYTE,x OF SHORT,y OF SHORT)
  9878.  
  9879.       At the call to the event procedure the parameter Down is TRUE  if the
  9880.       button was  pressed or  FALSE if it was released. x and y are the the
  9881.       mouse position coordinates.
  9882.  
  9883.       Example:
  9884.  
  9885.         DemoWindow.SelectEventHandler(Button(,,))
  9886.  
  9887.           :
  9888.  
  9889.         PROC Button(Down OF BYTE,x OF SHORT,y OF SHORT)
  9890.           <do anything>
  9891.         ENDPROC Button
  9892.  
  9893.  
  9894.     PROC MenuEventHandler(EventProc OF ButtonEventProc)
  9895.  
  9896.       By calling this the method the procedure EventProc will be called when
  9897.       the right mouse button (menu button) is pressed.
  9898.  
  9899.       For further description see SelectEventHandler.
  9900.  
  9901.       Note that this method must be called before the window is inserted in
  9902.       the screen. Alse note that after calling this  you cannot  have menus
  9903.       attached to the window.
  9904.  
  9905.  
  9906.     PROC PointerEventHandler(EventProc OF PointerEventProc)
  9907.  
  9908.       If the  method MouseMove  has been  called with the actual value TRUE
  9909.       the EventProc will be called when the mouse pointer is moved.
  9910.  
  9911.       EventProc is an event procedure of the form:
  9912.  
  9913.         PROC MousePos(x OF SHORT,y OF SHORT)
  9914.  
  9915.  
  9916.       At the call to the event procedure the parameters x and y are the the
  9917.       mouse position coordinates.
  9918.  
  9919.                                          174
  9920.  
  9921.  
  9922.  
  9923.  
  9924.  
  9925.  
  9926.       Note that you have to respond to the event very fast.
  9927.  
  9928.  
  9929.     PROC MouseMove(b OF SHORT)
  9930.  
  9931.       Start  mouse  move  event  calling.  As  described  above  your event
  9932.       procedure will be called if the parameter b has the value TRUE.
  9933.  
  9934.  
  9935.     PROC Coordinates(REF x OF SHORT,REF y OF SHORT)
  9936.  
  9937.       This method will return the current position coordinates of the mouse
  9938.       pointer.
  9939.  
  9940.       Example:
  9941.  
  9942.         DemoWindow.EventHandler(MouseMove(,))
  9943.         DemoWindow.MouseMove(TRUE)
  9944.           :
  9945.         PROC MouseMove(x OF SHORT,y OF SHORT)
  9946.           PRINT AT 20,5: USING "x = -### ,  y = -###": x,y,
  9947.         ENDPROC MouseMove
  9948.  
  9949.  
  9950.   A predefined  ready to  use window  ComalWindow is exported from the CIT-
  9951.   Window module. This is the standard IO window.
  9952.  
  9953.   Only the  methods InsObject,  RemObject, ToFront  and ToBack  can be used
  9954.   with ComalWindow  and the  window cannot  be removed  from its containing
  9955.   screen. Otherwise the window is used  in almost  the same  way as CITWin-
  9956.   dows. 
  9957.  
  9958.  
  9959.   11.3.4 CITBorder.
  9960.  
  9961.   The module CITBorder contains the window class objects CITBorder.
  9962.  
  9963.   The CITBorder  is used to draw borders in the window and is a rather spe-
  9964.   cial object that you will probably never use. It is inherited by the CITView
  9965.   and CITText. It contains the following methods:
  9966.  
  9967.  
  9968.     PROC Position(LeftEdge OF SHORT,TopEge OF SHORT)
  9969.  
  9970.       Set the position of the upper left corner of the border. Like gadgets
  9971.       the position coordinates may be negative. The the position of the upper
  9972.       left corner will be placed relative to the right and bottom border of
  9973.       the window.
  9974.  
  9975.  
  9976.                                          175
  9977.  
  9978.  
  9979.  
  9980.  
  9981.  
  9982.  
  9983.     PROC Size(Width OF USHORT,Height OF USHORT,Direc OF USHORT)
  9984.  
  9985.       Set the size of the border. The parameter Direc specifies if the border
  9986.       should be raised (use the value UP), recessed (use the value DOWN) or
  9987.       if there should be no visible border (use the value NOBORDER).
  9988.  
  9989.       The default size of the border is the size of  the containing element
  9990.       (CITWindow or CITView).
  9991.  
  9992.  
  9993.   The CITBorder  is inherited  by some  other WindowClass objects (CITView,
  9994.   CITText and CITGraphics).
  9995.  
  9996.  
  9997.  
  9998.  
  9999.   11.3.5 CITView.
  10000.  
  10001.   The CITView object is a WindowClass object that at first sight looks like
  10002.   the CITBorder (which it iherits) but it is a very special WindowClass object
  10003.   in that any WindowClass object (including the CITView itself) can be inser-
  10004.   ted in (and sometimes removed from) a CITView.
  10005.  
  10006.   A WindowClass object inserted in a CITView is placed relative to the bor-
  10007.   der of the view.
  10008.  
  10009.   The CITBorder contains the Size and Position methods  inherited from CIT-
  10010.   Border as  well as  InsObject and RemObject (see CITWindow for a descrip-
  10011.   tion of these methods).
  10012.  
  10013.  
  10014.   11.3.6 CITGadgets.
  10015.  
  10016.   In this module you will find a number of different gadgets to be inserted in
  10017.   a window.
  10018.  
  10019.   All these  gadgets are  member of  the class GadgetClass. Members of this
  10020.   class have these methods (with some minor individual modifications) along
  10021.   with other special methods:
  10022.  
  10023.     PROC Disable
  10024.  
  10025.       Disables the gadget so that the user cannot use it. Most of the gadgets
  10026.       will appear ghoasted.
  10027.  
  10028.  
  10029.     PROC Enable
  10030.  
  10031.       Enables the gadget.
  10032.  
  10033.                                          176
  10034.  
  10035.  
  10036.  
  10037.  
  10038.  
  10039.  
  10040.  
  10041.     PROC Position(LeftEdge OF SHORT,TopEdge OF SHORT)
  10042.  
  10043.       Set the position (of the upper left corner of the  gadget) inside the
  10044.       window (or view). If inserted in a window the parameters LeftEdge and
  10045.       TopEdge are relative to the inner of a window (excluding borders).
  10046.  
  10047.       If the parameters (one ore both) are negative the position of the gad-
  10048.       gets upper left corner will be relative to the right/lower border of the
  10049.       window (view).
  10050.  
  10051.  
  10052.     PROC Size(Width OF USHORT,Height OF USHORT)
  10053.  
  10054.       Set the width and height of the gadget.
  10055.  
  10056.  
  10057.     PROC Label(text$,Flags OF ULONG)
  10058.  
  10059.       Set a text to be shown with the gadget. The Flags is  used to specify
  10060.       the position and the highlightning status of the text:
  10061.  
  10062.       The position values are
  10063.  
  10064.         LEFT        -   place text to the left of the gadget
  10065.         RIGHT       -   place text to the right of the gadget
  10066.         ABOVE       -   place text above the gadget
  10067.         BELOW       -   place text below the gadget
  10068.         INSIDE      -   place text inside the gadget
  10069.  
  10070.  
  10071.       These position values may be BITORed (or added) with
  10072.  
  10073.         HIGHLIGHT   -   show text highlighted (white)
  10074.  
  10075.  
  10076.     PROC Font(Name$,Height OF SHORT)
  10077.  
  10078.       Set the name of the font to be used in the label. If the font cannot be
  10079.       found the default font (topaz80) will be used.
  10080.  
  10081.  
  10082.     PROC Id(ID OF USHORT)
  10083.  
  10084.       Set an identification number. This number is for your use only.
  10085.  
  10086.  
  10087.  
  10088.  
  10089.  
  10090.                                          177
  10091.  
  10092.  
  10093.  
  10094.  
  10095.  
  10096.     PROC EventHandler(p OF GadEventProc)
  10097.  
  10098.       By calling this method with a procedure p, this procedure will be called
  10099.       immediately if  the gadget  is activated  (for input gadgets when you
  10100.       press the <ENTER> key).
  10101.  
  10102.       The parameter p is a procedure with one  USHORT parameter  (the iden-
  10103.       tifiction  number set by the method Id).
  10104.  
  10105.  
  10106.   All the gadgets (except the TextGadget) have a current state. For all gad-
  10107.   gets this state can be read in the field Value (Value$ in the StringGadget).
  10108.  
  10109.   Note that this Value field should never be changed directly. If it is possible
  10110.   to change it, there will be a method available for this purpose.
  10111.  
  10112.  
  10113.  
  10114.   11.3.6.1 TextGadget.
  10115.  
  10116.   The TextGadget is a special read  only gadget.  A TextGadget  has a fixed
  10117.   label (set by the Label method) and a changeable text.
  10118.  
  10119.   The following methods are special for the TextGadget:
  10120.  
  10121.  
  10122.     PROC Text(t$)
  10123.  
  10124.       Set the  (changable) text.  The method  may be called both before and
  10125.       after the gadget has been inserted in a window.
  10126.  
  10127.  
  10128.     PROC Border
  10129.  
  10130.       Call this method to get a recessed border around the text.
  10131.  
  10132.  
  10133.   Example:
  10134.  
  10135.     DIM Text OF TextGadget
  10136.     Text.Position(214,5)
  10137.     Text.Text("CIT demo")
  10138.     DemoWindow.InsObject(Text,Error)
  10139.  
  10140.   Since this gadget is a read only gadget it makes no sence to add an event
  10141.   procedure to this gadget.
  10142.  
  10143.  
  10144.  
  10145.  
  10146.  
  10147.                                          178
  10148.  
  10149.  
  10150.  
  10151.  
  10152.  
  10153.   11.3.6.2 ButtonGadget.
  10154.  
  10155.   The well  known button gadget adds the following method to all the common
  10156.   methods:
  10157.  
  10158.  
  10159.      FUNC Pressed OF SHORT
  10160.  
  10161.       This boolean function returns  TRUE if  the gadget  has been pressed.
  10162.       The status of the gadget will be set to FALSE after the call.
  10163.  
  10164.  
  10165.  
  10166.   11.3.6.3 CheckboxGadget.
  10167.  
  10168.   The CheckboxGadget has the following methods:
  10169.  
  10170.     PROC On
  10171.  
  10172.       Set the state of the gadget to ON (the check mark will be shown). The
  10173.       method may be called both before and after the gadget has been inser-
  10174.       ted in a window.
  10175.  
  10176.  
  10177.     PROC Off
  10178.  
  10179.       Set the  state of the gadget to OFF (the check mark will be removed).
  10180.       The method may be called both  before and  after the  gadget has been
  10181.       inserted in a window.
  10182.  
  10183.  
  10184.   11.3.6.4 StringGadget.
  10185.  
  10186.   The StringGadget is used to enter a string of ASCII characters. This gadget
  10187.   has the following special method:
  10188.  
  10189.  
  10190.     PROC Replace
  10191.  
  10192.       Use this method to  change  the  typing  mode  to  the  replace mode.
  10193.       Otherwise it is insert mode. The method may only be called before the
  10194.       gadget has been inserted in a window.
  10195.  
  10196.  
  10197.     PROC TabCycle
  10198.  
  10199.       Make the gadget a TabCycle gadget. If the user types Tab or Shift-Tab
  10200.       into a  TabCycle gadget  the next or previous TabCycle gadget will be
  10201.       activated. The method may only be called before  the gadget  has been
  10202.       inserted in a window.
  10203.  
  10204.                                          179
  10205.  
  10206.  
  10207.  
  10208.  
  10209.  
  10210.  
  10211.  
  10212.     PROC MaxChar(n OF USHORT)
  10213.  
  10214.       This method  sets the  maximum number of input characters in the gad-
  10215.       get. The default number is 64. The method  may only  be called before
  10216.       the gadget has been inserted in a window.
  10217.  
  10218.  
  10219.     PROC Text(t$)
  10220.  
  10221.       Set the  content of the gadgets input field. The method may be called
  10222.       both before and after the gadget has been inserted in a window.
  10223.  
  10224.  
  10225.     PROC Activate
  10226.  
  10227.       Activate the gadget so that you can type in your text. The method may
  10228.       only be called after the gadget has been inserted in a window.
  10229.  
  10230.  
  10231.   Example:
  10232.  
  10233.     DIM StringGad OF StringGadget
  10234.     StringGad.Label("Type in a text",LEFT)
  10235.     StringGad.Position(150,48)
  10236.     StringGad.Size(170,15)
  10237.     DemoWindow.InsObject(StringGad,Error)
  10238.  
  10239.  
  10240.  
  10241.   11.3.6.5 IntegerGadget.
  10242.  
  10243.   The IntegerGadget is used to enter an integer number. This gadget has the
  10244.   following special method:
  10245.  
  10246.  
  10247.     PROC Replace
  10248.  
  10249.       Use this method to  change  the  typing  mode  to  the  replace mode.
  10250.       Otherwise it is insert mode. The method may only be called before the
  10251.       gadget has been inserted in a window.
  10252.  
  10253.  
  10254.     PROC TabCycle
  10255.  
  10256.       Make the gadget a TabCycle gadget. If the user types Tab or Shift-Tab
  10257.       into a  TabCycle gadget  the next or previous TabCycle gadget will be
  10258.       activated. The method may only be called before  the gadget  has been
  10259.       inserted in a window.
  10260.  
  10261.                                          180
  10262.  
  10263.  
  10264.  
  10265.  
  10266.  
  10267.  
  10268.  
  10269.     PROC MaxChar(n OF USHORT)
  10270.  
  10271.       This method  sets the  maximum number of input characters in the gad-
  10272.       get. The default number is 64. The method  may only  be called before
  10273.       the gadget has been inserted in a window.
  10274.  
  10275.  
  10276.     PROC Number(n OF ULONG)
  10277.  
  10278.       Set the  content of the gadgets input field. The method may be called
  10279.       both before and after the gadget has been inserted in a window.
  10280.  
  10281.  
  10282.     PROC Activate
  10283.  
  10284.       Activate the gadget so that you can type  in your  number. The method
  10285.       may only be called after the gadget has been inserted in a window.
  10286.  
  10287.  
  10288.  
  10289.   11.3.6.6 SliderGadget.
  10290.  
  10291.   A SliderGadget  is a  gadget used  to show  or control the amount of some
  10292.   quantity like a color, a volume or an intensity.
  10293.  
  10294.   This gadget has the following methods:
  10295.  
  10296.  
  10297.     PROC Limits(Min OF SHORT,Max OF SHORT)
  10298.     
  10299.       The method is used to set the level limits, i.e. the minimum and maxi-
  10300.       mum value  of the quantity in question. The method may only be called
  10301.       before the gadget has been inserted in a window.
  10302.  
  10303.  
  10304.     PROC Level(l OF SHORT)
  10305.  
  10306.       The method is use to set the actual level of the quantity. The method
  10307.       may be called both before and after the gadget has been inserted in a
  10308.       window.
  10309.  
  10310.  
  10311.   In the string used as parameter in the Label method (common for  all gad-
  10312.   gets) you  may place  the formatting  characters '#'  as in a PRINT USING
  10313.   statement. Then the current level will be printed.
  10314.  
  10315.  
  10316.  
  10317.  
  10318.                                          181
  10319.  
  10320.  
  10321.  
  10322.  
  10323.  
  10324.   Example:
  10325.  
  10326.       DIM SliderGad OF SliderGadget
  10327.       SliderGad.Position(150,88)
  10328.       SliderGad.Limits(0,100)
  10329.       SliderGad.Label("Fraction:###%",LEFT)
  10330.       DemoWindow.InsObject(SliderGad,Error)
  10331.  
  10332.     As a result of the line 
  10333.  
  10334.         SliderGad.Label("Fraction:###%",LEFT)
  10335.  
  10336.     a text of the form
  10337.  
  10338.         Fraction: 37%
  10339.  
  10340.     will be printed on the left side of the gadget.
  10341.  
  10342.  
  10343.  
  10344.  
  10345.   11.3.6.7 ScrollerGadget.
  10346.  
  10347.   A ScrollerGadget is a gadget used to show and/or adjust  the fraction and
  10348.   the position of a limited view into a larger area. The ScrollerGadget is a
  10349.   well known gadget. It is placed on the right side of the Comal editor win-
  10350.   dow and it is used in all the drawer windows opened by Workbench
  10351.  
  10352.   This gadget has the following methods:
  10353.  
  10354.  
  10355.     PROC Top(t OF SHORT)
  10356.  
  10357.       Sets the first visible position in the area that the scroller represents.
  10358.       The method may be called both  before and  after the  gadget has been
  10359.       inserted in a window.
  10360.  
  10361.  
  10362.     PROC Total(t OF SHORT)
  10363.  
  10364.       Sets the total size of the area that the scroller represents. The method
  10365.       may be called both before and after the gadget has been inserted in a
  10366.       window.
  10367.  
  10368.  
  10369.     PROC Visible(v OF SHORT)
  10370.  
  10371.       Sets the  number of  visible elements.  The method may be called both
  10372.       before and after the gadget has been inserted in a window.
  10373.  
  10374.  
  10375.                                          182
  10376.  
  10377.  
  10378.  
  10379.  
  10380.  
  10381.  
  10382.     PROC Arrows(Size OF SHORT)
  10383.  
  10384.       Place arrows at the end of the scroller. The parameter is the width of
  10385.       each arrow button for a horizontal scroller or the height for a vertical
  10386.       scroller. The default size is 10. Use a size value  of zero  to avoid
  10387.       arrows.
  10388.  
  10389.       The method  may only be called before the gadget has been inserted in
  10390.       a window.
  10391.  
  10392.  
  10393.     PROC Orientation(Or OF SHORT)
  10394.  
  10395.       Set the orientation of the scroller, The parameter values are:
  10396.  
  10397.         HORIZONTAL    -   make a horizontal scroller
  10398.         VERTICAL      -   make a vertical scroller
  10399.  
  10400.       The default orientation is horizontal.
  10401.  
  10402.       The method may only be called before the gadget has  been inserted in
  10403.       a window.
  10404.  
  10405.  
  10406.   The value found in the field Value is the current Top value.
  10407.  
  10408.  
  10409.   Example: Let's say we have a text of 137 lines (numbered 0 .. 136) and we
  10410.     can see 21 lines on the display (currently from line 32 to 52). The fol-
  10411.     lowing lines will create a scroller representing the text:
  10412.  
  10413.       DIM Scroler OF ScrollerGadget
  10414.       Scroller.Position(500,5)
  10415.       Scroller.Size(15,150)
  10416.       Scroller.Total(137)             // A total of 137 lines
  10417.       Scroller.Top(32)                // First visible (counting from zero)
  10418.       Scroller.Visible(21)            // 21 visible lines
  10419.       Scroller.Orientation(VERTICAL)
  10420.       DemoWindow.InsObject(Scroller,Error)
  10421.  
  10422.  
  10423.  
  10424.   11.3.6.8 CycleGadget.
  10425.  
  10426.   A CycleGadget is used to allow the user to choose one among several choi-
  10427.   ces. It appears as a raised rectangular button. A circular arrow glyph ap-
  10428.   pears to the left and the current choice to the right. Clicking once on the
  10429.   gadget the next choice in a list will appear, while shift-clicking will show
  10430.   the previous choice.
  10431.  
  10432.                                          183
  10433.  
  10434.  
  10435.  
  10436.  
  10437.  
  10438.  
  10439.   This gadget has the following methods:
  10440.  
  10441.  
  10442.     PROC Choices(REF Texts$())
  10443.  
  10444.       The texts in the array Texts$() (all texts or up to the first empty text)
  10445.       is the choices that will appear in the gadget. These texts must be valid
  10446.       through the whole lifetime of the gaget.
  10447.  
  10448.       The method  may be  called both  before and after the gadget has been
  10449.       inserted in a window.
  10450.  
  10451.  
  10452.     PROC Active(n OF SHORT)
  10453.  
  10454.       Sets the choice with the ordinal number n (counting from zero) as the
  10455.       active choice in the gadget.  The method may be called both before and
  10456.       after the gadget has been inserted in a window.
  10457.  
  10458.  
  10459.   Example:
  10460.  
  10461.     DIM CycleChoice$(4) OF 20
  10462.     READ CycleChoice$()
  10463.     DATA "Choice number 1"
  10464.     DATA "Choice number 2"
  10465.     DATA "Choice number 3"
  10466.     DATA "Choice number 4"
  10467.  
  10468.     DIM CycleGad OF CycleGadget
  10469.     CycleGad.Position(330,8)
  10470.     CycleGad.Size(190,14)
  10471.     CycleGad.Label("Press here",LEFT)
  10472.     CycleGad.Choices(CycleChoice$())
  10473.     CycleGad.Active(2)                    // 'Choice number 3'
  10474.     DemoWindow.InsObject(CycleGad,Error)
  10475.  
  10476.  
  10477.   11.3.6.9 RadioButtonGadget.
  10478.  
  10479.   Like the CycleGadget the RadioButtonGadget allow  the user  to choose one
  10480.   option from among several.
  10481.  
  10482.   All the choices are shown as a text beside a small raised oval that looks
  10483.   like a small radio button. Exactly one one button is recessed and highligh-
  10484.   ted to indicate the selected choice.
  10485.  
  10486.   This gadget has the following methods:
  10487.  
  10488.  
  10489.                                          184
  10490.  
  10491.  
  10492.  
  10493.  
  10494.  
  10495.     PROC Choices(REF Texts$(),Place OF ULONG)
  10496.  
  10497.       The texts in the array Texts$() (all texts or up to the first empty text)
  10498.       is the choices that will appear. These texts must be valid through the
  10499.       whole lifetime of the gaget.
  10500.  
  10501.       The parameter  Place specifies  where the  text is  to be placed. The
  10502.       values are:
  10503.  
  10504.         LEFT  - place text on the left side of the buttons
  10505.         RIGHT - place text on the right side of the buttons
  10506.  
  10507.       The method may only be called before the gadget has  been inserted in
  10508.       a window.
  10509.  
  10510.  
  10511.     PROC Spacing(s OF SHORT)
  10512.  
  10513.       Sets the amount of spacing (in pixels) between each button. The default
  10514.       value is zero (not very nice). The method may only be called before the
  10515.       gadget has been inserted in a window.
  10516.  
  10517.  
  10518.     PROC Active(n OF SHORT)
  10519.  
  10520.       Sets the choice with the ordinal number n (counting from zero) as the
  10521.       active choice in the gadget. The method may be called both before and
  10522.       after the gadget has been inserted in a window.
  10523.  
  10524.  
  10525.   11.3.6.10 ListViewGadget.
  10526.  
  10527.   A ListViewGadget,  like the CycleGadget and the RadioButtonGadget, allows
  10528.   the user to select one among several choices. It consists of a scroller with
  10529.   arrows, an area where the choices are visible and an optional place where
  10530.   the current selection is shown. The user can browse through the list using
  10531.   the scroller  or the  arrows and  may select an entry by clicking on that
  10532.   item.
  10533.  
  10534.   This gadget has the following methods:
  10535.  
  10536.  
  10537.     PROC ChoiceArray(REF Texts$())
  10538.  
  10539.       The texts in the array Texts$() (all texts or up to the first empty text)
  10540.       is the choices that will appear in the gadget. These texts must be valid
  10541.       through the whole lifetime of the gaget.
  10542.  
  10543.       The method may be called both  before and  after the  gadget has been
  10544.       inserted in a window.
  10545.  
  10546.                                          185
  10547.  
  10548.  
  10549.  
  10550.  
  10551.  
  10552.  
  10553.  
  10554.     PROC ChoiceList(REF List OF List)
  10555.  
  10556.       This is  an alternative way of supplying the choices. The choices are
  10557.       put ito the ln_Name field of an Exec list.
  10558.  
  10559.       The method may be called both  before and  after the  gadget has been
  10560.       inserted in a window.
  10561.  
  10562.  
  10563.     PROC Spacing(s OF USHORT)
  10564.  
  10565.       Sets the amount of spacing (in pixels) between each entry in the list-
  10566.       view. The default value is zero. The method may only be called before
  10567.       the gadget has been inserted in a window.
  10568.  
  10569.  
  10570.     PROC Top(n OF USHORT)
  10571.  
  10572.       The ordinal number (counting from zero) of the top item visible in the
  10573.       listview. The method may be called both before  and after  the gadget
  10574.       has been inserted in a window.
  10575.  
  10576.  
  10577.     PROC ScrollWidth(w OF USHORT)
  10578.  
  10579.       Sets the width of the scroller used in the listview. The method may be
  10580.       called only before the gadget has been inserted in a window.
  10581.  
  10582.  
  10583.     PROC ReadOnly
  10584.  
  10585.       Make the listview a read-only listview. The method may be called only
  10586.       before the gadget has been inserted in a window.
  10587.  
  10588.  
  10589.     PROC ShowSelected(REF StrgGad OF StringGadget)
  10590.  
  10591.       Use this method to attach a StringGadget to the listview. The currently
  10592.       selected item will be shown in the gadget  (ready to  be edited). The
  10593.       parameter StrgGad  must have  been created  (in a DIM or LOCAL state-
  10594.       ment) but not inserted in a window.
  10595.  
  10596.       The method may be called only before the gadget has  been inserted in
  10597.       a window.
  10598.  
  10599.  
  10600.  
  10601.  
  10602.  
  10603.                                          186
  10604.  
  10605.  
  10606.  
  10607.  
  10608.  
  10609.     PROC Selected(s OF USHORT)
  10610.  
  10611.       Ordinal number (counting from zero) of the item to be placed into the
  10612.       display under the listview.
  10613.  
  10614.       The method may be called both  before and  after the  gadget has been
  10615.       inserted in a window. If called before without a prior call of the Show-
  10616.       Selected method, a readonly TextGadget will be created.
  10617.  
  10618.   Example:
  10619.  
  10620.     DIM ListViewTexts$(4) OF 20
  10621.     ListViewTexts$(1):="Choice1"
  10622.     ListViewTexts$(2):="Choice2"
  10623.     ListViewTexts$(3):="Choice3"
  10624.     ListViewTexts$(4):="Choice4"
  10625.  
  10626.     DIM ListView OF ListViewGadget
  10627.     ListView.Position(200,128)
  10628.     ListView.Size(100,40)
  10629.     ListView.ChoiceArray(ListViewTexts$())
  10630.     ListView.Selected(1)                    // A TextGadget is created
  10631.     DemoWindow.InsObject(ListView,Error)
  10632.  
  10633.  
  10634.   11.3.6.11 PaletteGadget.
  10635.  
  10636.   The PaletteGadget lets the user pick a colour from a set of several. It con-
  10637.   sists of a number of coloured squares, one for each colour available.
  10638.  
  10639.   This gadget has the following methods:
  10640.  
  10641.  
  10642.     PROC Color(c OF UBYTE)
  10643.  
  10644.       The selected colour of the palette. Default is zero.
  10645.  
  10646.       The method  may be  called both  before and after the gadget has been
  10647.       inserted in a window.
  10648.  
  10649.  
  10650.     PROC IndicatorWidth(w)
  10651.  
  10652.       Specifies the width of the current-colour indicator. The default width is
  10653.       20 pixels.
  10654.  
  10655.       The method  may be called only before the gadget has been inserted in
  10656.       a window.
  10657.  
  10658.  
  10659.  
  10660.                                          187
  10661.  
  10662.  
  10663.  
  10664.  
  10665.  
  10666.     PROC IndicatorHeight(h)
  10667.  
  10668.       This method asks for a current-colour indicator to be placed above the
  10669.       the colour selection squares. The height is specified as a parameter.
  10670.  
  10671.       The method  may be called only before the gadget has been inserted in
  10672.       a window.
  10673.  
  10674.  
  10675.     PROC Depth(d OF SHORT)
  10676.  
  10677.       Specifies the number of bitplanes that the gadget represents. Default is
  10678.       two. The  method may be called only before the gadget has been inser-
  10679.       ted in a window.
  10680.  
  10681.  
  10682.     PROC ColorOffset(Offset OF SHORT)
  10683.  
  10684.       If there are more bitplanes in the screen than specified by the Depth
  10685.       method this is the number of the first colour to be displayed. Default
  10686.       is zero.
  10687.  
  10688.       The method may be called only before the gadget has  been inserted in
  10689.       a window.
  10690.  
  10691.  
  10692.   Example:
  10693.  
  10694.     DIM Palette OF PaletteGadget
  10695.     Palette.Position(350,128)
  10696.     Palette.Color(2)                      // Color 2 is the selected one
  10697.     DemoWindow.InsObject(Palette,Error)
  10698.  
  10699.  
  10700.  
  10701.  
  10702.   11.3.7 CITText.
  10703.  
  10704.   The module CITText contains the window class object CITText.
  10705.  
  10706.   The CITText  is used  to write  texts in the window. It contains the same
  10707.   methods as  CITBorder (it  inherits CITBorder)  as well  as the following
  10708.   methods:
  10709.  
  10710.  
  10711.     PROC PenColor(c OF SHORT)
  10712.  
  10713.       Set the colour of the drawing pen.
  10714.  
  10715.  
  10716.  
  10717.                                          188
  10718.  
  10719.  
  10720.  
  10721.  
  10722.  
  10723.     PROC BackColor(c OF SHORT)
  10724.  
  10725.       Set the colour of the back ground pen. This value is only used if the
  10726.       method Transparent is called with the parameter value FALSE.
  10727.  
  10728.  
  10729.     PROC Transparent(b OF SHORT)
  10730.  
  10731.       If b has the value TRUE the letters are drawn transparent, i.e. no back
  10732.       ground is drawn.
  10733.  
  10734.  
  10735.     PROC Font(Name$,Height OF SHORT)
  10736.  
  10737.       Set the  name of the font to be used. If the font cannot be found the
  10738.       default font (topaz80) will be used.
  10739.  
  10740.  
  10741.     PROC Print(x OF SHORT,y OF SHORT,t$)
  10742.  
  10743.       Print the text t$ at position x,y.
  10744.  
  10745.  
  10746.   Example:
  10747.  
  10748.     DIM Text OF CITText
  10749.     Text.Position(100,50)
  10750.     Text.Size(250,50,DOWN)
  10751.     DemoWindow.InsObject(Text,Error)
  10752.  
  10753.     Text.PenColor(3)
  10754.     Text.Font("times.font",24)
  10755.     Text.Print(10,10,"Hello world!")
  10756.  
  10757.  
  10758.  
  10759.  
  10760.   11.3.8 CITGraphics.
  10761.  
  10762.   CITGraphics in the module CITGraphics is a window class object containing
  10763.   a (very small) subset of the graphics routines of the Graphics module.
  10764.  
  10765.   It contains  the same methods as CITText (it inherits CITText) as well as
  10766.   the following methods:
  10767.  
  10768.     PROC Clear
  10769.  
  10770.       Clear the graphics area defined by Position and Size.
  10771.  
  10772.  
  10773.  
  10774.                                          189
  10775.  
  10776.  
  10777.  
  10778.  
  10779.  
  10780.     PROC Color(c OF SHORT)
  10781.  
  10782.       Set the color of the drawing pen.
  10783.  
  10784.  
  10785.     PROC MoveTo(x,y)
  10786.  
  10787.       Move (without drawing) the pen to the point with coordinates (x,y).
  10788.  
  10789.  
  10790.     PROC DrawTo(x,y)
  10791.  
  10792.       Draw a straight line from the current point to the point with coordina-
  10793.       tes (x,y).
  10794.  
  10795.  
  10796.     PROC Plot(x,y)
  10797.  
  10798.       Set a dot at the point with coordinates (x,y).
  10799.  
  10800.  
  10801.     PROC DrawText(x,y,t$)
  10802.  
  10803.       Print a text starting at the graphics coordinates (x,y). The Print me-
  10804.       thod of CITText is used to actually print the text.
  10805.  
  10806.  
  10807.     PROC Coordinates(Xmin,Xmax,Ymin,Ymax)
  10808.  
  10809.       Define a new coordinate system. Xmin and Xmax  will be  the new x-co-
  10810.       ordinates of the left and right edge of the drawing area. Ymin will be
  10811.       the new y-coordinate of the bottom edge and  Ymax wil  be the y-coor-
  10812.       dinate of the top edge.
  10813.  
  10814.  
  10815.   In CITGraphics all drawing are restricted to drawing area set by the Size
  10816.   method. This is also the case with DrawText.
  10817.  
  10818.  
  10819.  
  10820.   11.3.9 CITMenus.
  10821.  
  10822.   CITMenu in  the module  CITMenus is  a window  class object  used to make
  10823.   menus in a window. It contains the following methods:
  10824.  
  10825.  
  10826.     PROC Title(Label$,Flags OF USHORT,REF MenuId OF USHORT)
  10827.  
  10828.       Set the title of a new menu. The parameters are:
  10829.  
  10830.  
  10831.                                          190
  10832.  
  10833.  
  10834.  
  10835.  
  10836.  
  10837.         Label$
  10838.  
  10839.           The title (the headline) of a new series of menu items.
  10840.  
  10841.         Flags
  10842.  
  10843.           The only legal non zero value is
  10844.  
  10845.             DISABLED    disable this menu (all items and subitems) from start.
  10846.                         The menu can be enabled by calling the method On.
  10847.  
  10848.         MenuId
  10849.  
  10850.             An identification number is returned in this variable. The value is
  10851.             used in calls to the On and Off methods.
  10852.  
  10853.  
  10854.     PROC Item(Label$,Key$,Flags OF USHORT,Exlude OF LONG,
  10855.                               Prc OF MenuEvent,REF MenuId OF USHORT)
  10856.  
  10857.       Make a  new menu  item belonging to the menu created by the last call
  10858.       of the method Title. The parameters are:
  10859.  
  10860.         Label$
  10861.  
  10862.           The name of the menu item.
  10863.  
  10864.         Key$
  10865.  
  10866.           The first character in this string is used as a short cut for the
  10867.           menu item. If the string is the empty string there will be no short
  10868.           cut for this item.
  10869.  
  10870.         Flags
  10871.  
  10872.           This parameter can be zero or it can take on  one or  more of the
  10873.           following values:
  10874.  
  10875.             DISABLED    Disable the item (and all subitems belonging to it)
  10876.                         from start. The item can be enabled by  calling the
  10877.                         method On.
  10878.  
  10879.             CHECKIT     A check mark will be drawn to the left of the title
  10880.                         if the item is currently selected.
  10881.  
  10882.             MENUTOGGLE  By using this value the user  can toggle  the check
  10883.                         mark by selecting the item. Only to be used in con-
  10884.                         nection with the CHECKIT flag value.
  10885.  
  10886.                         Normally you will use this flag  in connection with
  10887.  
  10888.                                          191
  10889.  
  10890.  
  10891.  
  10892.  
  10893.  
  10894.                         the CHECKIT flag or you will set an exclude mask.
  10895.  
  10896.             CHECKED     Make the  item selected from start. Only to be used
  10897.                         in connection with the CHECKIT flag value.
  10898.  
  10899.           The values can be BITORed (or added) together.
  10900.  
  10901.         Exclude
  10902.  
  10903.           Set a 1 in a binary bitmask for each item  in this  (sub)menu you
  10904.           want to be deselected when the user selects this item. The right-
  10905.           most digit in the bitmask corresponds to the first item. Only to be
  10906.           used in connection with the CHECKIT flag value.
  10907.  
  10908.         Prc
  10909.  
  10910.           This is  an event  procedure with one unsigned short (USHORT) pa-
  10911.           rameter. This procedure will be called when the item is selected. At
  10912.           the call the actual parameter value will be the menu number retur-
  10913.           ned in the REF parameter MenuId. In this way you can identify the
  10914.           item if several items (or subitems) shares an event procedure.
  10915.  
  10916.         MenuId
  10917.  
  10918.           An identification number is returned in this variable. The value is
  10919.           used in calls to the On and Off methods.
  10920.  
  10921.  
  10922.     PROC SubItem(Label$,Key$,Flags OF USHORT,Exlude OF LONG,
  10923.                               Prc OF MenuEvent,REF MenuId OF USHORT)
  10924.  
  10925.       Create a subitem belonging to the last item.  The parameters  are the
  10926.       same as described above (the Item method).
  10927.  
  10928.  
  10929.     PROC Bar
  10930.  
  10931.       Make a separator bar between the previous and the next (sub)item.
  10932.  
  10933.  
  10934.     PROC On(MenuId OF USHORT)
  10935.  
  10936.       Enable the  menu or (sub)item identified by MenuId (the number retur-
  10937.       ned by calls to the methods Title, Item and SubItem).
  10938.  
  10939.  
  10940.     PROC Off(MenuId OF USHORT)
  10941.  
  10942.       Disable the menu or (sub)item identified by MenuId (the number retur-
  10943.       ned by calls to the methods Title, Item and SubItem).
  10944.  
  10945.                                          192
  10946.  
  10947.  
  10948.  
  10949.  
  10950.  
  10951.  
  10952.  
  10953.   Example:  This example  shows part of a program (most of the event proce-
  10954.     dures are not shown) creates a menu in the standard IO window.  
  10955.  
  10956.  
  10957.       USE CITWindow
  10958.       USE CITMenus
  10959.  
  10960.       DIM Terminate OF SHORT
  10961.  
  10962.       DIM Menu OF CITMenu
  10963.       Menu.Title("Project",0,ProjectId)
  10964.       Menu.Item("Open","O",0,0,PrcOpen(),OpenId)
  10965.       Menu.Item("Save","",0,0,PrcSave(),SaveId)
  10966.       Menu.Bar
  10967.       Menu.Item("Print Mode","",0,0,PrcMode(),ModeId)
  10968.       Menu.SubItem("Draft","",CHECKIT+CHECKED,%10,PrcMode(),DraftId)
  10969.       Menu.SubItem("NLQ","",CHECKIT,%01,PrcMode(),NLQId)
  10970.       Menu.Item("Print","P",0,0,PrcPrint(),PrintId)
  10971.       Menu.Bar
  10972.       Menu.Item("Quit","Q",0,0,PrcQuit(),QuitId)
  10973.       Menu.Title("Edit",0,EditId)
  10974.       Menu.Item("Cut","X",0,0,PrcCut(),CutId)
  10975.       Menu.Item("Copy","C",0,0,PrcCopy(),CopyId)
  10976.       Menu.Item("Paste","V",0,0,PrcPaste(),PasteId)
  10977.       Menu.Bar
  10978.       Menu.Item("Undo","Z",0,0,PrcUndo(),UndoId)
  10979.       ComalWindow.InsObject(Menu,Error)
  10980.  
  10981.       IF Error THEN
  10982.         PRINT "Could not create menu"
  10983.       ELSE
  10984.         WHILE NOT Terminate DO WAIT
  10985.         ComalWindow.RemObject(Menu)
  10986.       ENDIF
  10987.  
  10988.       // *********** Event procedures ************
  10989.  
  10990.       PROC PrcQuit(Num OF USHORT)
  10991.         Terminate:=TRUE
  10992.       ENDPROC PrcQuit
  10993.  
  10994.       PROC PrcOpen(Num OF USHORT)
  10995.         :
  10996.       ENDPROC PrcOpen
  10997.  
  10998.       PROC PrcSave(Num OF USHORT)
  10999.         :
  11000.  
  11001.  
  11002.                                          193
  11003.  
  11004.  
  11005.  
  11006.  
  11007.  
  11008.  
  11009.  
  11010.   11.3.10 CITRequester.
  11011.  
  11012.   CITRequester in the module CITRequesters is a window class object used to
  11013.   make system requesters in a window. It contains only one method:
  11014.  
  11015.  
  11016.       FUNC Request(Text$,YesNo$) OF LONG
  11017.  
  11018.         The parameters are:
  11019.  
  11020.         Text$:  This is the body text of the requester. This text may contain
  11021.                 C-language formatting characters, or the new line character,
  11022.                 CHR$(10).
  11023.  
  11024.         YesNo$: The gadget  text for  one or more gadgets in the requester.
  11025.                 Each gadget text is separated by the chracter '|'.
  11026.  
  11027.         The return value is zero if the rightmost gadget was pressed. Other-
  11028.         wise the return value is the number of the gadget (counting from the
  11029.         left).
  11030.  
  11031.         Example:
  11032.  
  11033.           DIM Rq OF CITRequester
  11034.  
  11035.             :
  11036.  
  11037.           CASE Rq.Request("Text modified"10"Save text?","Yes|No|Cancel") OF
  11038.           WHEN 0
  11039.  
  11040.             :
  11041.  
  11042.           WHEN 1
  11043.  
  11044.             :
  11045.  
  11046.           WHEN 2
  11047.  
  11048.             :
  11049.  
  11050.           ENDCASE
  11051.  
  11052.  
  11053.  
  11054.   11.4 Creating your own CIT classes.
  11055.  
  11056.   In principle it is a simple task to make new CIT types belonging to one of
  11057.   the excisting CITClasses: WorkbenchClass, ScreenClasss, WindowClass etc.
  11058.  
  11059.                                          194
  11060.  
  11061.  
  11062.  
  11063.  
  11064.  
  11065.  
  11066.   But before we can do this it is necessary to know a little more about how
  11067.   CIT works.
  11068.  
  11069.   All the CIT classes (except the base class CITWorkbench) contain two cen-
  11070.   tral methods:
  11071.  
  11072.       FUNC CreateObject(REF Alfa OF CITAlfa, .. ) OF SHORT VIRTUAL
  11073.  
  11074.       PROC DeleteObject VIRTUAL
  11075.  
  11076.  
  11077.   and in addition all the WindowClasses contain an event method:
  11078.  
  11079.       PROC HandleEvent(REF Msg OF IntuiMessage) VIRTUAL
  11080.  
  11081.  
  11082.  
  11083.   The value  of the  first parameter in the CreateObject method is the con-
  11084.   tainer object into which this object is to be placed. This method may have
  11085.   some other parameters as indicated.
  11086.  
  11087.   As can be seen in a lot of examples, an AlfaClass object is inserted in a
  11088.   CITAlfa object by executing a line of the form:
  11089.  
  11090.     Alfa.InsObject(AlfaClassObject,Error)
  11091.  
  11092.  
  11093.   The method InsObject now calls the method CreateObject in AlfaClassObject
  11094.   and it is in fact this method that does the actual insertion. After a succes-
  11095.   full return from CreateObject the container  object Alfa  inserts the new
  11096.   object in a book keeping list such that it knows which objects are current-
  11097.   ly inserted.
  11098.  
  11099.   It can also be seen from the examples, that an AlfaClass object is removed
  11100.   from a CITAlfa object by executing a line of the form:
  11101.  
  11102.     Alfa.RemObject(AlfaClassObject)
  11103.  
  11104.  
  11105.   The method  RemObject now  calls the  method DeleteObject in AlfaClassOb-
  11106.   ject and after that removes it from its book keeping list. If AlfaClassObject
  11107.   itself contains inserted object the DeleteObject method in AlfaClassObject
  11108.   has to remove all its inserted objects (i.e. it calls the DeleteObject method
  11109.   in all the inserted object).
  11110.  
  11111.   If an  AlfaClass event occurs, the object Alfa traverses the book keeping
  11112.   list and calls the HandleEvent method in all the inserted  objects one by
  11113.   one.
  11114.  
  11115.  
  11116.                                          195
  11117.  
  11118.  
  11119.  
  11120.  
  11121.  
  11122.   An important  requiremet for  this to work with many different objects is
  11123.   that the methods CreateObject, DeleteObject and  HandleEvent are declared
  11124.   as virtual methods.
  11125.  
  11126.   To make a new AlfaClass type you have to define a structure that inherits
  11127.   the base class AlfaClass or one of its ancestors. In this structure you will
  11128.   probably define new data fields and you are likely to overload one or more
  11129.   of the virtual methods CreateObject, DeleteObject and HandleEvent.
  11130.  
  11131.   Here is a typical example:
  11132.  
  11133.     STRUC ExtAlfa
  11134.       INHERIT AlfaClass
  11135.  
  11136.           :
  11137.       < some data fields >
  11138.           :
  11139.  
  11140.       FUNC CreateObject(REF Alfa OF CITAlfa) OF SHORT VIRTUAL
  11141.  
  11142.         // First create the ancestor object
  11143.         IF AlfaClass.CreateObject(Alfa) THEN
  11144.  
  11145.           < do other ExtAlfa specific creation >
  11146.  
  11147.           RETURN TRUE
  11148.         ELSE
  11149.           RETURN FALSE
  11150.         ENDIF
  11151.  
  11152.       ENDFUNC CreateObject
  11153.  
  11154.       PROC DeleteObject VIRTUAL
  11155.  
  11156.         < do ExtAlfa specific deletion >
  11157.  
  11158.         // Finally delete the ancestor object
  11159.         AlfaClass.DeleteObject
  11160.  
  11161.       ENDPROC DeleteObject
  11162.  
  11163.       < other methods >
  11164.  
  11165.     ENDSTRUC ExtAlfa
  11166.  
  11167.  
  11168.   Note that the base class AlfaClass defined in connection with the definition
  11169.   of the  CITAlfa type  is only a skeleton. It would not make much sence to
  11170.   create an object of this type (although it is possible). It is defined as fol-
  11171.   low:
  11172.  
  11173.                                          196
  11174.  
  11175.  
  11176.  
  11177.  
  11178.  
  11179.  
  11180.     STRUC AlfaClass
  11181.       METHODTABLE
  11182.  
  11183.       DIM CITAlfa OF POINTER TO CITAlfa
  11184.  
  11185.       PROC Terminate DESTRUCTOR
  11186.         IF CITAlfa THEN
  11187.           LOCAL AlfaClass OF POINTER TO AlfaClass
  11188.  
  11189.           AlfaClass:=ADR(CITAlfa)-4
  11190.           CITAlfa@.RemObject(AlfaClass@)
  11191.         ENDIF
  11192.       ENDPROC Terminate
  11193.  
  11194.       FUNC CreateObject(REF Alfa OF CITAlfa, .. ) OF SHORT VIRTUAL
  11195.         CITAlfa:=ADR(Alfa)
  11196.         RETURN TRUE
  11197.       ENDFUNC CreateObject
  11198.  
  11199.       PROC DeleteObject VIRTUAL
  11200.         CITAlfa:=0
  11201.       ENDPROC DeleteObject
  11202.  
  11203.       PROC HandleEvent(REF Msg OF IntuiMessage) VIRTUAL
  11204.       ENDPROC HandleEvent
  11205.  
  11206.     ENDSTRUC AlfaClass
  11207.  
  11208.  
  11209.   The CreateObject method stores a pointer to the container object (you are
  11210.   free to use this in your own extensions) and DeleteObject deletes this poin-
  11211.   ter. The destructor Terminate removes the object if the object is going to
  11212.   loose its data area (at return from a procedure for instance).
  11213.  
  11214.   The HandleEvent method is only present in the WindowClass.
  11215.  
  11216.   You should look into  the modules  CITWorkbench, CITScreen  and CITWindow
  11217.   to see  the actual definitions (there are some minor differences from the
  11218.   general scheme) and to see what the content of the actual container object
  11219.   is.
  11220.  
  11221.   Example:  As a  complete example we will make an extension of the CITWin-
  11222.     dow (a member of the ScreenClass). This extension  should have  a fixed
  11223.     default position and size and an Ok-button in the lower left corner.
  11224.  
  11225.     In addition  there should be a method Wait. This method will wait until
  11226.     the Ok-button has been pressed.
  11227.  
  11228.     The definition could be made in this way:
  11229.  
  11230.                                          197
  11231.  
  11232.  
  11233.  
  11234.  
  11235.  
  11236.  
  11237.       STRUC MyWindow
  11238.         INHERIT CITWindow
  11239.  
  11240.         USE CITGadgets
  11241.         USE IntuitionScreen
  11242.  
  11243.         DIM CloseButton OF ButtonGadget
  11244.  
  11245.         FUNC Init CONSTRUCTOR
  11246.           NewWindow.LeftEdge:=50
  11247.           NewWindow.TopEdge:=30
  11248.           NewWindow.Width:=500
  11249.           NewWindow.Height:=150
  11250.           CloseButton.Size(60,14)
  11251.           CloseButton.Position(5,-(14+3))
  11252.           CloseButton.Label("STOP",INSIDE)
  11253.           RETURN TRUE
  11254.         ENDFUNC Init
  11255.  
  11256.         FUNC CreateObject(REF CITScr OF CITScreen0) OF SHORT VIRTUAL
  11257.           LOCAL Error OF SHORT
  11258.  
  11259.           IF CITWindow.CreateObject(CITScr) THEN
  11260.             InsObject(CloseButton,Error)
  11261.             IF Error THEN
  11262.               CITWindow.DeleteObject
  11263.               RETURN FALSE
  11264.             ELSE
  11265.               RETURN TRUE
  11266.             ENDIF
  11267.           ELSE
  11268.             RETURN FALSE
  11269.           ENDIF
  11270.         ENDFUNC CreateObject
  11271.  
  11272.         PROC Wait
  11273.           WHILE NOT CloseButton.Pressed DO WAIT
  11274.         ENDPROC Wait
  11275.  
  11276.       ENDSTRUC MyWindow
  11277.  
  11278.     Note that there is no DeleteObject  in the  structure. The DeleteObject
  11279.     method in CITWindow will do the work.
  11280.  
  11281.  
  11282.   You should  look through  the different CIT-modules to see other examples
  11283.   on definition of CIT classes.
  11284.  
  11285.  
  11286.  
  11287.                                          198
  11288.  
  11289.  
  11290.  
  11291.  
  11292.  
  11293.   V. MAKING EXECUTABLE PROGRAMS
  11294.  
  11295.   There are two ways to make executable programs (i.e. programs that can be
  11296.   started by clicking on its icon) out of a Comal program text.
  11297.  
  11298.   One way  is to  store the  program as a code file. To execute the program
  11299.   the whole Comal system (the interpreter and all modules used  in the pro-
  11300.   gram) must be present on the system disk.
  11301.  
  11302.   Another way is to combine the interpreter, the program and all the modules
  11303.   used by the program into one executable file.  This file  can be executed
  11304.   without the presence of the Comal system.
  11305.  
  11306.  
  11307.   1 Comal code file.
  11308.  
  11309.   A Comal  program can  be stored  on disk as a code file by using the menu
  11310.   item Save.. in the Programs menu.
  11311.  
  11312.   By double clicking on the icon created along with the code file, the pro-
  11313.   gram is started (without loading the editor).
  11314.  
  11315.   The program  can be  started from  the Shell (CLI) by executing a command
  11316.   like:
  11317.  
  11318.       Comal.Starter [parameters] ProgramName
  11319.  
  11320.  
  11321.   Example:
  11322.  
  11323.       Comal.Starter SCREEN=Workbench Bitplane=3 Programs/DemoProgram
  11324.  
  11325.     The parameter SCREEN=Workbench is  used by  Comal.Starter. Both parame-
  11326.     ters can be read by the program.
  11327.  
  11328.  
  11329.   The program is executed as a separate process and the current directory at
  11330.   start is the directory containing the code file.
  11331.  
  11332.   The code file is much shorter than the combined file described in the next
  11333.   section and  it is  the best  way to make an executable file if the Comal
  11334.   system is present.
  11335.  
  11336.  
  11337.   2 Combined files.
  11338.  
  11339.   The Combiner combines the interpreter, a program and all modules  used by
  11340.   this program into one single file that can be executed independent of the
  11341.   Comal system.
  11342.  
  11343.  
  11344.                                          199
  11345.  
  11346.  
  11347.  
  11348.  
  11349.  
  11350.   The Combiner strips off the comments from the  program and  all the Comal
  11351.   modules and it strips off the information text from mashine coded modules
  11352.   in the SystemModules directory before it combines it.
  11353.  
  11354.   The combined file can be executed by double clicking on  the icon created
  11355.   by the  Combiner or by starting it from the Shell (CLI) in the normal way
  11356.   (startup parameters are managed just like TOOLTYPE's put into the icon).
  11357.  
  11358.   The current directory at start of the execution is the directory containing
  11359.   the file.
  11360.  
  11361.  
  11362.   2.1 Starting the Combiner from the editor.
  11363.  
  11364.   The simplest  way to  make a  combined file is to start the Combiner from
  11365.   the editor by using the Combine.. menu item in the  Programs menu. Before
  11366.   the Combiner is started a file requester will pop up, and you may select the
  11367.   name and destination of the combined file.
  11368.  
  11369.   The current workspace size and stack size as well as the current state of
  11370.   Automatic Variables and Execute Window are used as default values for the
  11371.   combined file (may be changed by using the Tool Types in the icon).
  11372.  
  11373.   If the editor uses the Workbench screen, the Tool Type
  11374.  
  11375.       SCREEN=Workbench
  11376.  
  11377.   is put into the icon of the combined file.
  11378.  
  11379.  
  11380.  
  11381.   2.2 Starting the Combiner from Workbench.
  11382.  
  11383.   The Combiner can be started from the Workbench. Activate the  icon of the
  11384.   Combiner by clicking once on its icon, press the shift key and double click
  11385.   on the icon of a program (text or code).
  11386.  
  11387.   The following Tool Types can be put into the icon of the  Combiner or the
  11388.   icon of the program:
  11389.  
  11390.  
  11391.     SCREEN
  11392.  
  11393.       The only legal value is Workbench:
  11394.  
  11395.         SCREEN=Workbench
  11396.  
  11397.       The default value is a private screen.
  11398.  
  11399.  
  11400.  
  11401.                                          200
  11402.  
  11403.  
  11404.  
  11405.  
  11406.  
  11407.     AUTOVAR
  11408.  
  11409.       This tool type is used to select the default AutoVar state of the com-
  11410.       bined file. The default value for the Combiner is On.
  11411.  
  11412.       Example:  AUTOVAR=Off
  11413.  
  11414.  
  11415.     EXECWINDOW
  11416.  
  11417.       This tool type is used to select the default ExecWindow  state of the
  11418.       combined file. The default value for the Combiner is On.
  11419.  
  11420.  
  11421.     WORKSPACE
  11422.  
  11423.       Selects the  size of  the workspace used by the combined program. The
  11424.       default value is 75000 bytes.
  11425.  
  11426.       Example:  WORKSPACE=60000
  11427.  
  11428.  
  11429.     STACK
  11430.  
  11431.       Selects the size of the stack, if the combined program is started from
  11432.       Workbench. The default value is 8Kb.
  11433.  
  11434.       Example:  STACK=16000
  11435.  
  11436.       If the  combined program is started from the Shell, the stack size of
  11437.       the Shell will be used.
  11438.  
  11439.  
  11440.     OUTPUT
  11441.  
  11442.       Specify the path and/or the name of the ouput from the combiner.
  11443.  
  11444.       Example:  OUTPUT=Comal:Programs/
  11445.                 OUTPUT=ram:Hanoi
  11446.  
  11447.       If the name ends with ':' or '/' the tool value is treated as a path and
  11448.       the name of the output will be the same as the input file name.
  11449.  
  11450.  
  11451.   If no output file path is specified the name of the combined file will be the
  11452.   name of the input file with the extension '.cmb'.
  11453.  
  11454.  
  11455.  
  11456.  
  11457.  
  11458.                                          201
  11459.  
  11460.  
  11461.  
  11462.  
  11463.  
  11464.   2.3 Starting the Combiner from the Shell (CLI).
  11465.  
  11466.   The Combiner may be started from the Shell. The command is:
  11467.  
  11468.       Combiner [options] ProgramName
  11469.  
  11470.  
  11471.   The options are the same as the Tool Types used if the Combiner is started
  11472.   from the Workbench.
  11473.  
  11474.   Example:
  11475.  
  11476.       Combiner OUTPUT=ram: WORKSPACE=50000 Demos/Polygon2
  11477.  
  11478.  
  11479.  
  11480.   3 Using ToolTypes in executable files.
  11481.  
  11482.   The field Tool Types inside the icon of an executable file (a code file or a
  11483.   combined file) is where you can set parameters for the program.
  11484.  
  11485.   The TOOLTYPE's and the ToolValue's recognized  by the  system are descri-
  11486.   bed below. All TOOLTYPE's are transfered to the program.
  11487.  
  11488.  
  11489.     SCREEN
  11490.  
  11491.       By using the SCREEN tool type you select if Comal should open its own
  11492.       screen or use the workbench screen. The only legal value is Workbench.
  11493.  
  11494.         SCREEN=Workbench
  11495.  
  11496.       The default value is a private  screen. But  this screen  will not be
  11497.       opened if EXECWINDOW is set to Off.
  11498.  
  11499.  
  11500.     AUTOVAR
  11501.  
  11502.       This tool type is used to select if the program should create variables
  11503.       automatically or if all variables has to be declared in a DIM or LOCAL
  11504.       statement before use.
  11505.  
  11506.       Example:  AUTOVAR=Off
  11507.  
  11508.  
  11509.     EXECWINDOW
  11510.  
  11511.       This tool type is used to select if the program should open the stan-
  11512.       dard execute window (used by PRINT, INPUT etc.). The default value is
  11513.       On.
  11514.  
  11515.                                          202
  11516.  
  11517.  
  11518.  
  11519.  
  11520.  
  11521.  
  11522.       Example:  EXECWINDOW=Off
  11523.  
  11524.  
  11525.     WORKSPACE
  11526.  
  11527.       Selects the  size of  the workspace  used by the program. The default
  11528.       value is 75000 bytes.
  11529.  
  11530.       Example:  WORKSPACE=60000
  11531.  
  11532.  
  11533.  
  11534.  
  11535.  
  11536.  
  11537.  
  11538.  
  11539.  
  11540.  
  11541.  
  11542.  
  11543.  
  11544.  
  11545.  
  11546.  
  11547.  
  11548.  
  11549.  
  11550.  
  11551.  
  11552.  
  11553.  
  11554.  
  11555.  
  11556.  
  11557.  
  11558.  
  11559.  
  11560.  
  11561.  
  11562.  
  11563.  
  11564.  
  11565.  
  11566.  
  11567.  
  11568.  
  11569.  
  11570.  
  11571.  
  11572.                                          203
  11573.  
  11574.  
  11575.  
  11576.  
  11577.  
  11578.   VI. DESCRIPTION OF THE Comal SYSTEM
  11579.  
  11580.   The Comal system consists of several program files. During normal program
  11581.   devellopment three of these program files are used. These files are:
  11582.  
  11583.     Comal
  11584.  
  11585.       The editor
  11586.  
  11587.     Comal.CodeMan
  11588.  
  11589.       A program  used to manipulate the program buffer. It generates inter-
  11590.       mediate code from ASCII lines and regenerate ASCII  lines from inter-
  11591.       mediate code. It inserts new lines in the buffer and deletes lines from
  11592.       the buffer. And much more.
  11593.  
  11594.     Comal.Interpreter
  11595.  
  11596.       The interpreter that executes your programs.
  11597.  
  11598.  
  11599.   The programs are executed  as separate  processes. The  editor Comal com-
  11600.   municates with Comal.CodeMan and Comal.Interpreter by sending messages.
  11601.  
  11602.  
  11603.   1 The code manipulator Comal.CodeMan.
  11604.  
  11605.   The program  Comal.CodeMan is used to manipulate the program buffer. Once
  11606.   started it will stay as a resident process and all comumnication with the
  11607.   process goes through its message port Comal.CodeMan.
  11608.  
  11609.   A message  send to this port must be either a RexxMessage (explained in a
  11610.   later section) or it must be of the form:
  11611.  
  11612.     STRUC CodeCommandMsg
  11613.       INHERIT Message
  11614.       DIM Command OF POINTER TO CodeCommand
  11615.     ENDSTRUC CodeCommandMsg
  11616.  
  11617.   where Message is a standard Exec message and CodeCommand is
  11618.  
  11619.     STRUC CodeCommand
  11620.       DIM Cmd OF SHORT
  11621.       DIM Status OF SHORT
  11622.       DIM PrgBuf OF POINTER TO PrgBuf
  11623.       DIM Param1 OF ULONG
  11624.       DIM Param2 OF ULONG
  11625.       DIM CmdProc@ OF CmdProc
  11626.     ENDSTRUC CodeCommand
  11627.  
  11628.  
  11629.                                          204
  11630.  
  11631.  
  11632.  
  11633.  
  11634.  
  11635.  
  11636.   Before a message is send to  Comal.CodeMan the  Cmd field  is set  to the
  11637.   command  you  want  to  be  executed  and the fields Param1 and Param2 is
  11638.   filled with corresponding command parameters.
  11639.  
  11640.   Before Comal.CodeMan returns the  message, it  places the  command status
  11641.   code in the field Status (zero is ok) and return values in the fields Param1
  11642.   and Param2.
  11643.  
  11644.   The command that can be executed are:
  11645.  
  11646.     CODE_KILL (1)           Kill CodeMan process
  11647.  
  11648.       If there are no open program  buffers the  Comal.CodeMan process will
  11649.       be removed.
  11650.  
  11651.       There are no return values from this command.
  11652.  
  11653.  
  11654.     CODE_OPEN (2)           Open program buffer
  11655.  
  11656.       Create a  new program  buffer. If  status is ok the fields PrgBuf and
  11657.       CmdProc is set. CmdProc can be used to call CodeMan  directly without
  11658.       sending a message (considerably faster).
  11659.  
  11660.       Command parameters:   Param1 = program buffer length
  11661.                             Param2 = initial flags
  11662.  
  11663.       Return values:        None
  11664.  
  11665.  
  11666.     CODE_CLOSE (3)          Close program buffer
  11667.  
  11668.       A  program   buffer  previously   opened  by  executing  the  command
  11669.       CODE_OPEN is closed.
  11670.  
  11671.       Command parameters:   None
  11672.  
  11673.       Return values:        None
  11674.  
  11675.  
  11676.     CODE_CLEAR (4)          Clear program buffer
  11677.  
  11678.       Remove the current content of the program buffer.
  11679.  
  11680.       Command parameters:   None
  11681.  
  11682.       Return values:        None
  11683.  
  11684.  
  11685.  
  11686.                                          205
  11687.  
  11688.  
  11689.  
  11690.  
  11691.  
  11692.     CODE_LOAD (5)           Read file into program buffer
  11693.  
  11694.       Read program stored on disk in code form into the program buffer. The
  11695.       previous content of the program buffer is lost.
  11696.  
  11697.       Command parameters:   Param1 = Pointer to null terminated file name
  11698.  
  11699.       Return values:        Param1 = Line number
  11700.                             Param2 = Total number of lines in buffer
  11701.  
  11702.       Note: Since Comal.CodeMan  runs as a separate process (unless CmdProc
  11703.             is used) the complete path for the file must be specified.
  11704.  
  11705.  
  11706.     CODE_SAVE (6)           Write program buffer to file
  11707.  
  11708.       The content of the program buffer is stored on disk in code form. The
  11709.       program buffer is unchanged.
  11710.  
  11711.       Command parameters:   Param1 = Pointer to null terminated file name
  11712.  
  11713.       Return values:        None
  11714.  
  11715.       Note: Since Comal.CodeMan  runs as a separate process (unless CmdProc
  11716.             is used) the complete path for the file must be specified.
  11717.  
  11718.  
  11719.     CODE_GEN (7)            Generate code for ASCII line
  11720.  
  11721.       Intermediate code is generated for an ASCII program line. If an error
  11722.       occurs the return parameter Param1 points to the place where the error
  11723.       was detected.
  11724.  
  11725.       Command parameters:   Param1 = Pointer to null terminated program line
  11726.                             Param2 = Address of buffer for the code
  11727.  
  11728.       Return values:        Param1 = Pointer into program line
  11729.                             Param2 = Address of buffer for the code
  11730.  
  11731.       Note: The buffer must be large enough to hold the code generated (500
  11732.             bytes is recommented).
  11733.  
  11734.  
  11735.     CODE_GENDIRECT (8)
  11736.  
  11737.       Intermediate code is generated for an ASCII program line. An error is
  11738.       reported if the code generated cannot be executed directly (if the pro-
  11739.       gram line is part of a program structure). If an error occurs the return
  11740.       parameter Param1 points to the place where the error was detected.
  11741.  
  11742.  
  11743.                                          206
  11744.  
  11745.  
  11746.  
  11747.  
  11748.  
  11749.       Command parameters:   Param1 = Pointer to null terminated program line
  11750.                             Param2 = Address of buffer for the code
  11751.  
  11752.       Return values:        Param1 = Pointer into program line
  11753.                             Param2 = Address of buffer for the code
  11754.  
  11755.       Note: The buffer must be large enough to hold the code generated (500
  11756.             bytes is recommented).
  11757.  
  11758.  
  11759.     CODE_REGEN (9)          Regenerate ASCII line
  11760.  
  11761.       Regenerate the current line (pointed at by the buffer pointer) into the
  11762.       corresponding ASCII line. This command can be viewed of as the rever-
  11763.       se of CODE_GEN.
  11764.  
  11765.       Command parameters:   Param1 = ASCII buffer pointer
  11766.  
  11767.       Return values:        Param1 = Length of ASCII line generated
  11768.                             Param2 = Line number of current line
  11769.  
  11770.       Note: The generated ASCII line is null terminated and the length retur-
  11771.             ned includes the terminating zero
  11772.  
  11773.  
  11774.     CODE_INSERT (10)        Insert code line in buffer
  11775.  
  11776.       Insert intermediate code line in program buffer at the current position.
  11777.  
  11778.       Command parameters:   Param1 = Address of code
  11779.  
  11780.       Return values:        Param1 = Line number of current line
  11781.                             Param2 = Total number of lines in buffer
  11782.  
  11783.  
  11784.     CODE_DELETE (11)        Delete current line in buffer
  11785.  
  11786.       The current line in buffer is deleted
  11787.  
  11788.       Command parameters:   None
  11789.  
  11790.       Return values:        Param1 = Line number of current line
  11791.                             Param2 = Total number of lines in buffer
  11792.  
  11793.  
  11794.     CODE_REPLACE (12)       Replace line in buffer
  11795.  
  11796.       Replace the current line with the code given as parameter.  This is a
  11797.       combination of CODE_DELETE and CODE_INSERT.
  11798.  
  11799.  
  11800.                                          207
  11801.  
  11802.  
  11803.  
  11804.  
  11805.  
  11806.       Command parameters:   Param1 = Address of code
  11807.  
  11808.       Return values:        Param1 = Line number of current line
  11809.                             Param2 = Total number of lines in buffer
  11810.  
  11811.  
  11812.     CODE_UP (13)            Move pointer n lines up
  11813.  
  11814.       Move the buffer pointer up n lines (or to top of buffer).
  11815.  
  11816.       Command parameters:   Param1 = Number of lines to move up
  11817.  
  11818.       Return values:        Param1 = Line number of current line
  11819.                             Param2 = Total number of lines in buffer
  11820.  
  11821.  
  11822.     CODE_DOWN (14)          Move pointer n lines down
  11823.  
  11824.       Move the buffer pointer down n lines (or to buttom of buffer).
  11825.  
  11826.       Command parameters:   Param1 = Number of lines to move down 
  11827.  
  11828.       Return values:        Param1 = Line number of current line
  11829.                             Param2 = Total number of lines in buffer
  11830.  
  11831.  
  11832.     CODE_BOB (15)           Move pointer to bottom of buffer
  11833.  
  11834.       Move the buffer pointer to bottom of buffer.
  11835.  
  11836.       Command parameters:   None  
  11837.  
  11838.       Return values:        Param1 = Line number of current line
  11839.                             Param2 = Old line number
  11840.  
  11841.  
  11842.     CODE_TOB (16)           Move pointer to top of buffer
  11843.  
  11844.       Move the buffer pointer to top of buffer.
  11845.  
  11846.       Command parameters:   None  
  11847.  
  11848.       Return values:        Param1 = 1
  11849.                             Param2 = Old line number
  11850.  
  11851.     CODE_SETADR (17)        Set pointer to specified address
  11852.  
  11853.       The code pointer is set to the line containing the specified address
  11854.  
  11855.       Command parameter:    Param1 = address
  11856.  
  11857.                                          208
  11858.  
  11859.  
  11860.  
  11861.  
  11862.  
  11863.  
  11864.       Return values:        Param1 = Line number of current line
  11865.                             Param2 = Address offset in current line
  11866.  
  11867.  
  11868.     CODE_SETFLAGS (18)      Set flags
  11869.  
  11870.       Set the CodeMan flags
  11871.  
  11872.       Command parameters:   Param1 = New flag values of flags to chage
  11873.                             Param2 = Mask of flag bits to change
  11874.  
  11875.       Return values:        Param1 = new flag values
  11876.                             Param2 = old flag values
  11877.  
  11878.  
  11879.   Flags:
  11880.     $0001:  List standard identifiers in capital
  11881.     $0002:  List in PC format
  11882.  
  11883.  
  11884.   Status codes returned by CODE_OPEN:
  11885.  
  11886.     NOMEM (1)           Cannot allocate memory
  11887.     NUMINITERR (2)      IEEE initialization error
  11888.  
  11889.  
  11890.   Status code  returned by other commands:                                 
  11891.  
  11892.     NOTDIRECT (1)       Not direct command
  11893.     NOBUFSPACE (2)      Not enough room in program buffer 
  11894.     ENDOFBUF (3)        Pointer at end of buffer
  11895.     ADDRNOTFOUND (4)    Address not found in programbuffer
  11896.     NOFILE (5)          File not found
  11897.     READERROR (6)       Error during reading
  11898.     WRITEERROR (7)      Error during writing
  11899.     ILLFORMAT (8)       Not legal Comal program file
  11900.     CODEMANINUSE (9)    Cannot kill CodeMan
  11901.  
  11902.   All the structures and symbolic names are defined in the  module CodeMan-
  11903.   Include.
  11904.  
  11905.   The following  procedure CodeToAscii is an example of the use of the com-
  11906.   mands. The procedure changes a code program file to an ASCII text file.
  11907.  
  11908.  
  11909.     PROC CodeToAscii(Name$,NewName$) CLOSED
  11910.       USE System
  11911.       USE InterpreterInclude
  11912.       USE ExecLists
  11913.  
  11914.                                          209
  11915.  
  11916.  
  11917.  
  11918.  
  11919.  
  11920.       USE PortObjects
  11921.       USE ExecLibrary
  11922.  
  11923.       DIM CodeManPort OF POINTER TO MsgPort
  11924.       DIM CodeManMsg OF CodeCommandMsg
  11925.       DIM ReplyPort OF MsgPort
  11926.       DIM Command OF CodeCommand
  11927.       DIM Buffer(500) OF UBYTE
  11928.  
  11929.       CodeManMsg.mn_ReplyPort:=ADR(ReplyPort)
  11930.  
  11931.       // Find CodeMan port
  11932.       CodeManPort:=FindPort("Comal.CodeMan")
  11933.       IF CodeManPort=0 THEN
  11934.         CleanUp
  11935.         STOP
  11936.       ENDIF
  11937.  
  11938.       // .. and open CodeMan
  11939.       Command.Cmd:=CODE_OPEN
  11940.       Command.Param1:=$8000
  11941.       Command.Param2:=0
  11942.       SendCommand(Command)
  11943.       IF Command.Status THEN
  11944.         CleanUp
  11945.         STOP
  11946.       ENDIF
  11947.  
  11948.       Command.Cmd:=CODE_LOAD
  11949.       Command.Param1:=ADR(Name$)
  11950.       Command.Param2:=0
  11951.       SendCommand(Command)
  11952.       IF Command.Status THEN
  11953.         CleanUp
  11954.         STOP
  11955.       ENDIF
  11956.  
  11957.       OPEN FILE 1,NewName$,WRITE
  11958.       REPEAT
  11959.         Command.Cmd:=CODE_REGEN
  11960.         Command.Param1:=ADR(Buffer())
  11961.         Command.Param2:=0
  11962.         SendCommand(Command)
  11963.         IF Command.Status THEN
  11964.           CleanUp
  11965.           STOP
  11966.         ENDIF
  11967.         PRINT FILE 1: CharArrayToString$(ADR(Buffer()))
  11968.         Command.Cmd:=CODE_DOWN
  11969.         Command.Param1:=1
  11970.  
  11971.                                          210
  11972.  
  11973.  
  11974.  
  11975.  
  11976.  
  11977.         Command.Param2:=0
  11978.         SendCommand(Command)
  11979.       UNTIL Command.Status
  11980.  
  11981.       CleanUp
  11982.  
  11983.       PROC SendCommand(REF Command OF CodeCommand)
  11984.         CodeManMsg.Command:=ADR(Command)
  11985.         CodeManPort@.Put(CodeManMsg)
  11986.         CodeManMsg.Wait
  11987.       ENDPROC SendCommand
  11988.  
  11989.       PROC CleanUp
  11990.         IF Command.CmdProc THEN
  11991.           Command.Cmd:=CODE_CLOSE
  11992.           Command.CmdProc@(ADR(Command))
  11993.           Command.CmdProc:=0
  11994.         ENDIF
  11995.         CLOSE
  11996.       ENDPROC CleanUp
  11997.  
  11998.     ENDPROC CodeToAscii
  11999.  
  12000.  
  12001.   2 The interpreter Comal.Interpreter.
  12002.  
  12003.   The program Comal.Interpreter is used to execute a  program. Once started
  12004.   it will stay as a resident process and all communication with the process
  12005.   goes through message ports.
  12006.  
  12007.   A message send to the port must be either a  RexxMessage (explained  in a
  12008.   later section) or it must be of the form:
  12009.  
  12010.     STRUC InterpreterCommandMsg
  12011.       INHERIT Message
  12012.       DIM Command OF POINTER TO InterpreterCommand
  12013.     ENDSTRUC InterpreterCommandMsg
  12014.  
  12015.   where  Message  is  a  standard  Exec message and InterpreterCommand is a
  12016.   structure of the form:
  12017.  
  12018.  
  12019.     STRUC InterpreterCommand
  12020.       DIM Cmd OF SHORT           // Put your command in here
  12021.       DIM Status OF SHORT        // Look for command status here
  12022.       DIM Int_Port@ OF MsgPort   // Use this port in communication
  12023.       DIM Task@ OF Task          // Interpreter task pointer
  12024.       DIM BreakSigMask OF ULONG  // Signal used to stop running program
  12025.       DIM Param1 OF ULONG        // 1. parameter
  12026.       DIM Param2 OF ULONG        // 2. parameter
  12027.  
  12028.                                          211
  12029.  
  12030.  
  12031.  
  12032.  
  12033.  
  12034.       DIM Param3 OF ULONG        // 3. parameter
  12035.       DIM Flags OF ULONG
  12036.     ENDSTRUC InterpreterCommand
  12037.  
  12038.  
  12039.   Before a message is send to Comal.Interpreter the Cmd field is set to the
  12040.   command you  want to be executed and the fields Param1 and Param2 is fil-
  12041.   led with corresponding command parameters. Before the message is returned,
  12042.   the command status code in the field Status (zero is ok) and return values
  12043.   in the fields Param1, Param2 and Param3 are set.
  12044.  
  12045.   The command that can be executed are:
  12046.  
  12047.  
  12048.     INT_KILL (1)            Kill interpreter
  12049.  
  12050.       If there are no active interpreters the master process Comal.Interpreter
  12051.       will be removed. A non zero status means that the master process can-
  12052.       not be closed (others are using it). There are no  command parameters
  12053.       or return values.
  12054.  
  12055.  
  12056.     INT_OPEN (2)            Open interpreter
  12057.  
  12058.       A new interpreter is opened. The new interpreter is in fact a new pro-
  12059.       cess and all the next commands are send to the  port returned  in the
  12060.       field Int_Port.
  12061.  
  12062.       Command parameters:   Param1 = address of open structure
  12063.                             Param2 = stack size of new process
  12064.                             Param3 = RUN flags (only if LOAD and RUN)
  12065.  
  12066.       The open structure has the form:
  12067.  
  12068.         STRUC IntOpenStruc
  12069.           DIM Flags OF ULONG
  12070.           DIM WorkspaceLength OF ULONG
  12071.           DIM PrgId OF POINTER TO UBYTE
  12072.           DIM IO_Port OF POINTER TO MsgPort
  12073.           DIM Screen OF POINTER TO Screen
  12074.           DIM InterpreterId OF POINTER TO UBYTE
  12075.         ENDSTRUC IntOpenStruc
  12076.  
  12077.       and the open flags are:
  12078.  
  12079.         INTOPEN_AUTOVAR  ($00000001)    Automatic creation of variables
  12080.         INTOPEN_COMMPORT ($00000002)    Create communication port
  12081.         INTOPEN_LOADPRG  ($20000000)    Open and load program.
  12082.         INTOPEN_OPENSCR  ($40000000)    Open separate screen
  12083.         INTOPEN_LOADRUN  ($A0000000)    Load and run as separate process
  12084.  
  12085.                                          212
  12086.  
  12087.  
  12088.  
  12089.  
  12090.  
  12091.  
  12092.       If flag  bit 29  is set  (LOADPRG and  LOADRUN) the  field PrgId is a
  12093.       pointer to a null terminated file name. Otherwise it is an address of a
  12094.       program buffer (returned by CODE_OPEN command to Comal.CodeMan).
  12095.  
  12096.       return values:        Param1 =  address of communication port (if the
  12097.                             INTOPEN_COMMPORT is set)
  12098.  
  12099.  
  12100.     INT_CLOSE (3)           Close program buffer
  12101.  
  12102.       Close the interpreter and remove  the  process  created  by INT_OPEN.
  12103.       The master process Comal.Interpreter is not closed.
  12104.  
  12105.       Command parameters:   None
  12106.  
  12107.       Return values:        None
  12108.  
  12109.  
  12110.     INT_SCAN (4)            Scan program
  12111.  
  12112.       Make a  prepass scan of the program. The address returned can be send
  12113.       to CodeMan (CODE_SETADR) to get the exact error position.
  12114.  
  12115.       Command parameters:   None
  12116.  
  12117.       Return value:         Param1 = active program buffer
  12118.                             Param2 = pointer into program line (if error)
  12119.  
  12120.  
  12121.     INT_RUN (5)             Execute program
  12122.  
  12123.       Execute program in main program buffer.  The address  returned can be
  12124.       send to  CodeMan (CODE_SETADR)  to get  the exact  error position. If
  12125.       the run flag RUNFLAG_STDIO  ($00000001)  is  set,  an  execute window
  12126.       will be  the standard  IO device.  Otherwise the  IO_Port in the open
  12127.       structure is used.
  12128.       
  12129.       Command parameters:   Param1 = flags
  12130.  
  12131.       Return values:        Param1 = active program buffer
  12132.                             Param2 = pointer into program line (if error)
  12133.                             Param3 = address of return text
  12134.  
  12135.  
  12136.     INT_COMMAND (6)         Execute line as command
  12137.  
  12138.       Execute a single code line as command.
  12139.  
  12140.       Command parameters:   Param1 = pointer to line
  12141.  
  12142.                                          213
  12143.  
  12144.  
  12145.  
  12146.  
  12147.  
  12148.  
  12149.       Return values:        Param1 = active program buffer
  12150.                             Param2 = pointer into program line (if error)
  12151.                             Param3 = address of return text
  12152.  
  12153.  
  12154.     INT_CONTINUE (7)        Continue
  12155.  
  12156.       Continue breaked program execution
  12157.  
  12158.       Command parameters:   None
  12159.  
  12160.       Return values:        None
  12161.  
  12162.  
  12163.     INT_RETPRGBUF (8)       Return program buffer
  12164.  
  12165.       The  commands  INT_SCAN,  INT_RUN,  INT_COMMAND  transfers  the  pro-
  12166.       gram buffer  to the interpreter and you are not allowed to change the
  12167.       buffer. To get the program buffer back execute this command.
  12168.  
  12169.       Command parameters:   None
  12170.  
  12171.       Return values:        None
  12172.  
  12173.  
  12174.     INT_DISCARD (9)         Remove all modules
  12175.  
  12176.       Remove all modules loaded.
  12177.  
  12178.       Command parameters:   None
  12179.  
  12180.       Return values:        None
  12181.  
  12182.  
  12183.     INT_LISTMODULES (10)    Return list of all modules
  12184.  
  12185.       A list of module structures for all modules are returned.
  12186.  
  12187.       Command parameters:   None
  12188.  
  12189.       Return values:        Param1 = address of first structure in list
  12190.  
  12191.  
  12192.     INT_STARTTRACE (11)     Initiate tracing mode
  12193.  
  12194.       Scan program and start tracing. No lines are executed.
  12195.  
  12196.       Command parameters:   None
  12197.  
  12198.  
  12199.                                          214
  12200.  
  12201.  
  12202.  
  12203.  
  12204.  
  12205.       Return values:        Param1 = active program buffer
  12206.                             Param2 = pointer into line (if error)
  12207.                             Param3 = return text
  12208.  
  12209.  
  12210.     INT_STOPTRACE (12)      Stop tracing mode
  12211.  
  12212.       Command parameters:   None
  12213.  
  12214.       Return values:        None
  12215.  
  12216.  
  12217.     INT_SINGLESTEP (13)     Execute one step
  12218.  
  12219.       Execute one step of program. The program must be in tracing mode.
  12220.  
  12221.       Command parameters:   None
  12222.  
  12223.       Return values:        Param1 = program buffer
  12224.                             Param2 = pointer to line (if error)
  12225.                             Param3 = return text
  12226.  
  12227.  
  12228.     INT_LINESTEP (14)       Execute one line
  12229.  
  12230.       Execute one line of program. The program must be in tracing mode.
  12231.  
  12232.       Command parameters:   None
  12233.  
  12234.       Return values:        Param1 = program buffer
  12235.                             Param2 = pointer to line (if error)
  12236.                             Param3 = return text
  12237.  
  12238.  
  12239.     INT_SETBREAK (15)       Set break point
  12240.  
  12241.       Set break point at specified line in program or module
  12242.  
  12243.       Command parameters:   Param1 = address of program buffer
  12244.                             Param2 = line number of break point line
  12245.  
  12246.       Return values:        None
  12247.  
  12248.  
  12249.     INT_CLEARBREAK (16)     Clear break point
  12250.  
  12251.       Clear break point at specified line
  12252.  
  12253.       Command parameters:   Param1 = address of program buffer
  12254.                             Param2 = line number of break point line
  12255.  
  12256.                                          215
  12257.  
  12258.  
  12259.  
  12260.  
  12261.  
  12262.  
  12263.       Return values:        None
  12264.  
  12265.  
  12266.     INT_CLEARALL (17)       Clear all break points
  12267.  
  12268.       Clear all break points in main program and modules.
  12269.  
  12270.       Command parameters:   None
  12271.  
  12272.       Return values:        None
  12273.  
  12274.  
  12275.  
  12276.   Status codes returned by INT_OPEN:
  12277.  
  12278.     NOMEM (1)           Cannot allocate memory
  12279.     NUMINITERR (2)      IEEE initialization error
  12280.  
  12281.  
  12282.   Status codes returned by all other commands are the same as is  send by a
  12283.   running program.
  12284.  
  12285.   The structures and all the symbolic names are defined in the module Inter-
  12286.   preterInclude.
  12287.  
  12288.   The following procedure StartProgram is an example of the use of the com-
  12289.   mands. The procedure starts a program stored as a code program file.
  12290.  
  12291.  
  12292.     PROC StartProgram(PrgName$) CLOSED
  12293.       USE System
  12294.       USE InterpreterInclude
  12295.       USE ExecLists
  12296.       USE PortObjects
  12297.       USE ExecLibrary
  12298.  
  12299.       DIM IntCmd OF InterpreterCommand
  12300.       DIM IntCmdMsg OF InterpreterCommandMsg
  12301.       DIM ReplyPort@ OF MsgPort, ReplySigMask OF ULONG
  12302.       DIM MasterPort@ OF MsgPort
  12303.       DIM OpenStruc OF IntOpenStruc
  12304.       DIM RetSigMask OF ULONG
  12305.       DIM pos OF SHORT
  12306.  
  12307.       // Find Interpreter master port
  12308.       MasterPort:=FindPort(MasterPortName$)
  12309.       IF MasterPort=0 THEN
  12310.         STOP "Cannot find interpreter master"
  12311.       ENDIF
  12312.  
  12313.                                          216
  12314.  
  12315.  
  12316.  
  12317.  
  12318.  
  12319.  
  12320.       // Remove path from program name
  12321.       pos:=LEN(PrgName$)+1
  12322.       REPEAT
  12323.         pos:-1
  12324.       UNTIL pos=0 OR PrgName$(pos..pos)=":" OR PrgName$(pos..pos)="/"
  12325.       Name$:=PrgName$(pos+1..)
  12326.  
  12327.       OpenStruc.Flags:=INTOPEN_LOADRUN BITOR INTOPEN_AUTOVAR
  12328.       OpenStruc.WorkspaceLength:=$8000
  12329.       OpenStruc.PrgId:=ADR(PrgName$)
  12330.       OpenStruc.Screen:=0                 // Use Workbench screen
  12331.       OpenStruc.IO_Port:=0                // No IO port
  12332.       OpenStruc.InterpreterId:=ADR(Name$) // Id of new process
  12333.  
  12334.       IntCmdMsg.mn_ReplyPort:=ADR(ReplyPort)
  12335.       IntCmdMsg.Command:=ADR(IntCmd)
  12336.       IntCmd.Cmd:=INT_OPEN
  12337.       IntCmd.Param1:=ADR(OpenStruc)
  12338.       IntCmd.Param2:=$4000                // Stack size
  12339.       IntCmd.Param3:=RUNFLAG_STDIO
  12340.       MasterPort@.Put(IntCmdMsg)
  12341.       IntCmdMsg.Wait
  12342.  
  12343.       IF IntCmd.Status<>0 THEN
  12344.         STOP "Cannot load program"
  12345.       ENDIF
  12346.  
  12347.       // The program is started - return
  12348.  
  12349.     ENDPROC StartProgram
  12350.  
  12351.  
  12352.  
  12353.   3 The starter program Comal.Starter.
  12354.  
  12355.   The  default   tool  for  a  Comal  code  program  file  is  the  program
  12356.   Comal.Starter. This program loads the interpreter Comal.Interpreter (if not
  12357.   already loaded)  and opens an interpreter process that reads the file and
  12358.   executes  it  as  a  stand  alone  process  by   using  the   open  flags
  12359.   INTOPEN_LOADRUN (almost like the procedure StartProgram in section 2).
  12360.  
  12361.   Having done this the Comal.Starter terminates.
  12362.  
  12363.  
  12364.  
  12365.  
  12366.  
  12367.  
  12368.  
  12369.  
  12370.                                          217
  12371.  
  12372.  
  12373.  
  12374.  
  12375.  
  12376.   VII. THE Comal AREXX INTERFACE
  12377.  
  12378.   Each of  the three  main parts  of the Comal system (Comal, Comal.CodeMan
  12379.   and Comal.Interpreter) has an  AREXX interface.  This chapter  covers the
  12380.   commands supported and how to access them.
  12381.  
  12382.  
  12383.   1 The editor AREXX interface.
  12384.  
  12385.   For each  project opened a separate process is started with its own AREXX
  12386.   port. The name of the port is Comal.Project.<project number>, for instance
  12387.   Comal.Project.001 and Comal.Project.002.
  12388.  
  12389.   The AREXX  commands accepted  by the  editor are  (NOTE: for all commands
  12390.   the return code is RC_WARN (5) if the command is currently disabled):
  12391.  
  12392.  
  12393.     NEW                 Create a new project
  12394.  
  12395.       Command format: NEW
  12396.  
  12397.       Return values:  The name of the AREXX port of the project
  12398.  
  12399.       Return codes:   RC_OK (0) if success
  12400.                       RC_ERROR (10) if the command failed
  12401.  
  12402.       Example:        NEW
  12403.  
  12404.  
  12405.     CLEAR             Clear program buffer
  12406.  
  12407.       Command format: CLEAR [FORCE]
  12408.  
  12409.       Return values:  None
  12410.  
  12411.       Return codes:   RC_OK (0) if success
  12412.                       RC_WARN (5) if user pressed the NO gadget
  12413.  
  12414.       If the program in the program buffer has been changed the user will be
  12415.       prompted to accept unless the FORCE argument is specified.
  12416.  
  12417.       Example:        CLEAR FORCE
  12418.  
  12419.  
  12420.     OPEN              Open and load a new project file
  12421.  
  12422.       Command format: OPEN [FILENAME=<name>][MODE=ASCII|CODE][FORCE]
  12423.  
  12424.       Return values:  None
  12425.  
  12426.  
  12427.                                          218
  12428.  
  12429.  
  12430.  
  12431.  
  12432.  
  12433.       Return codes:   RC_OK (0) if success
  12434.                       RC_WARN (5) if NO or CANCEL gadget pressed
  12435.                       RC_ERROR (10) if illegal or no file
  12436.  
  12437.       If the file name is not specified the user is prompted for a file name
  12438.       via the file requester. The MODE argument specifies the file type (an
  12439.       ASCII text file or a Comal code file). The default mode is ASCII. If the
  12440.       program in the program buffer  has  been  changed  the  user  will be
  12441.       prompted to accept unless the FORCE argument is specified.
  12442.  
  12443.       Example:        OPEN FILENAME=Demos/Integral1 FORCE
  12444.  
  12445.  
  12446.     SAVE              Save project
  12447.  
  12448.       Command format: SAVE [MODE=ASCII|CODE]
  12449.  
  12450.       Return values:  None
  12451.  
  12452.       Return codes:   RC_OK (0) if success
  12453.                       RC_WARN (5) if CANCEL gadget pressed
  12454.                       RC_ERROR (10) else
  12455.  
  12456.       The MODE  argument specifies  the file  type (an ASCII text file or a
  12457.       Comal code file). The default mode is ASCII. If the current project is
  12458.       unnamed the user is prompted for a file name via the file requester.
  12459.  
  12460.       Example:        SAVE CODE
  12461.  
  12462.  
  12463.  
  12464.     SAVEAS            Save project under specified name
  12465.  
  12466.       Command format: OPEN [FILENAME=<name>] [MODE=ASCII|CODE]
  12467.  
  12468.       Return values:  None
  12469.  
  12470.       Return codes:   RC_OK (0) if success
  12471.                       RC_WARN (5) if NO or CANCEL gadget pressed
  12472.                       RC_ERROR (10) if illegal or no file
  12473.  
  12474.       If the file name is not specified the user is prompted for a file name
  12475.       via the file requester. The MODE argument specifies the file type (an
  12476.       ASCII text file or a Comal code file).
  12477.  
  12478.       Example:        SAVEAS FILENAME=Programs/Hanoi CODE
  12479.  
  12480.  
  12481.  
  12482.  
  12483.  
  12484.                                          219
  12485.  
  12486.  
  12487.  
  12488.  
  12489.  
  12490.     PRINT             Output the program to printer
  12491.  
  12492.       Command format: PRINT
  12493.  
  12494.       Return values:  None
  12495.  
  12496.       Return codes:   RC_OK (0)
  12497.  
  12498.       Example:        PRINT
  12499.  
  12500.  
  12501.     QUIT              Terminate the project
  12502.  
  12503.       Command format: QUIT [FORCE]
  12504.  
  12505.       Return values:  None
  12506.  
  12507.       Return codes:   RC_OK (0) if success
  12508.                       RC_WARN (5) if user pressed the NO gadget
  12509.  
  12510.       If the program in the program buffer has been changed the user will be
  12511.       prompted to accept unless the FORCE argument is specified.
  12512.  
  12513.       Example:        QUIT
  12514.  
  12515.  
  12516.     BLOCK             Set block mode on/off
  12517.  
  12518.       Command format: BLOCK
  12519.  
  12520.       Return values:  ON or OFF dependent on  the  block  mode  state after
  12521.                       the command is executed.
  12522.  
  12523.       Return codes:   RC_OK (0)
  12524.  
  12525.       Example:        BLOCK
  12526.  
  12527.  
  12528.     BLOCKSIZE         Return the size of the current block
  12529.  
  12530.       Command format: BLOCKSIZE
  12531.  
  12532.       Return values:  The returned  number is  in fact  not the size of the
  12533.                       block. The number of lines in the block  is -RetVal+1
  12534.                       if RetVal<0 and RetVal+1 else. The number can be used
  12535.                       directly as an argument in the  LINE command  to move
  12536.                       to the other end of the block.
  12537.  
  12538.       Return codes:   RC_OK (0)
  12539.  
  12540.  
  12541.                                          220
  12542.  
  12543.  
  12544.  
  12545.  
  12546.  
  12547.       Example:        BLOCKSIZE
  12548.  
  12549.  
  12550.     CUT               Move marked block to the clip board
  12551.  
  12552.       Command format: CUT
  12553.  
  12554.       Return values:  None.
  12555.  
  12556.       Return codes:   RC_OK (0) if success
  12557.                       RC_ERROR (10) if out of memory
  12558.  
  12559.       Example:        CUT
  12560.  
  12561.  
  12562.     COPY              Move a copy of the marked block to the clip board
  12563.  
  12564.       Command format: COPY
  12565.  
  12566.       Return values:  None.
  12567.  
  12568.       Return codes:   RC_OK (0) if success
  12569.                       RC_ERROR (10) if out of memory
  12570.  
  12571.       Example:        COPY
  12572.  
  12573.  
  12574.     PASTE             Insert content of clipboard into the program
  12575.  
  12576.       Command format: PASTE
  12577.  
  12578.       Return values:  None.
  12579.  
  12580.       Return codes:   RC_OK (0) if success
  12581.                       RC_ERROR (10) if out of memory
  12582.  
  12583.       Example:        PASTE
  12584.  
  12585.  
  12586.     ERASE             Delete marked block
  12587.  
  12588.       Command format: ERASE
  12589.  
  12590.       Return values:  None.
  12591.  
  12592.       Return codes:   RC_OK (0)
  12593.  
  12594.       Example:        ERASE
  12595.  
  12596.  
  12597.  
  12598.                                          221
  12599.  
  12600.  
  12601.  
  12602.  
  12603.  
  12604.     CURSOR            Move cursor
  12605.  
  12606.       Command format: CURSOR UP|DOWN|LEFT|RIGHT
  12607.  
  12608.       Return values:  None
  12609.  
  12610.       Return codes:   RC_OK (0) if success
  12611.                       RC_WARN (5) if border of text
  12612.  
  12613.       Example:        CURSOR DOWN
  12614.  
  12615.  
  12616.     POSITION          Move cursor to specified position
  12617.  
  12618.       Command format: POSITION <place>  where place is:
  12619.                         SOF start of file
  12620.                         EOF end of file
  12621.                         SOL start of line
  12622.                         EOL end of line
  12623.                         SOV start of view (top of window)
  12624.                         EOV end of view (bottom of window)
  12625.  
  12626.       Return values:  None
  12627.  
  12628.       Return codes:   RC_OK (0)
  12629.  
  12630.       Example.        POSITION EOF
  12631.  
  12632.  
  12633.     LINE              Move cursor up/down specified number of lines
  12634.  
  12635.       Command format: LINE <number>
  12636.  
  12637.       Return values:  None.
  12638.  
  12639.       Return codes:   RC_OK (0) if success
  12640.                       RC_WARN (5) if border of text
  12641.  
  12642.       Example:        LINE -5     /* Move 5 lines up  */
  12643.  
  12644.  
  12645.     COLUMN            Move cursor left/right specified number of characters
  12646.  
  12647.       Command format: COLUMN <number>
  12648.  
  12649.       Return values:  None.
  12650.  
  12651.       Return codes:   RC_OK (0) if success
  12652.                       RC_WARN (5) if border of text
  12653.  
  12654.  
  12655.                                          222
  12656.  
  12657.  
  12658.  
  12659.  
  12660.  
  12661.       Example:        COLUMN 5    /* Move 5 characters right  */
  12662.  
  12663.  
  12664.  
  12665.     TEXT              Write the text argument at current cursor position
  12666.  
  12667.       Command format: TEXT text
  12668.  
  12669.       Return values:  None.
  12670.  
  12671.       Return codes:   RC_OK (0)
  12672.  
  12673.       Example:        TEXT ' this text will be written'
  12674.  
  12675.  
  12676.     NEWLINE           Output a CR character
  12677.  
  12678.       Command format: NEWLINE
  12679.  
  12680.       Return values:  None.
  12681.  
  12682.       Return codes:   RC_OK (0)
  12683.  
  12684.       The command has the same effect as pressing the enter key.
  12685.  
  12686.       Example:        NEWLINE
  12687.  
  12688.  
  12689.     INSLINE           Insert en empty line at the cursor position
  12690.  
  12691.       Command format: INSLINE
  12692.  
  12693.       Return values:  None.
  12694.  
  12695.       Return codes:   RC_OK (0)
  12696.  
  12697.       Example:        INSLINE
  12698.  
  12699.  
  12700.     DELCHAR           Delete character under cursor
  12701.  
  12702.       Command format: DELCHAR
  12703.  
  12704.       Return values:  None.
  12705.  
  12706.       Return codes:   RC_OK (0)
  12707.  
  12708.       Example:        DELCHAR
  12709.  
  12710.  
  12711.  
  12712.                                          223
  12713.  
  12714.  
  12715.  
  12716.  
  12717.  
  12718.     DELLINE           Delete cursor line
  12719.  
  12720.       Command format: DELLINE
  12721.  
  12722.       Return values:  None.
  12723.  
  12724.       Return codes:   RC_OK (0)
  12725.  
  12726.       Example:        DELLINE
  12727.  
  12728.  
  12729.     GETTEXT           Get the content of cursor line
  12730.  
  12731.       Command format: GETTEXT
  12732.  
  12733.       Return values:  The cursor line.
  12734.  
  12735.       Return codes:   RC_OK (0)
  12736.  
  12737.       Example:        GETTEXT
  12738.  
  12739.  
  12740.     WRITESTATUS       Write text in status line
  12741.  
  12742.       Command format: WRITESTATUS text
  12743.  
  12744.       Return values:  None.
  12745.  
  12746.       Return codes:   RC_OK (0)
  12747.  
  12748.       Example:        WRITESTATUS 'this text will be written'
  12749.  
  12750.  
  12751.     GETFILE           Get file from file requester
  12752.  
  12753.       Command format: GETFILE [FILENAME=<Name>][HAIL=<HailText>]
  12754.  
  12755.       Return values:  Selected file name (including full path).
  12756.  
  12757.       Return codes:   RC_OK (0) if success
  12758.                       RC_WARN (5) if CANCEL gadget presse
  12759.  
  12760.       The command will open a file requester. If a file name is specified this
  12761.       name will be written as the current file. The hail test will be written
  12762.       in the top of the file requester window.
  12763.  
  12764.       Example:        GETFILE FILENAME=System.mod HAIL=Select a module
  12765.  
  12766.  
  12767.  
  12768.  
  12769.                                          224
  12770.  
  12771.  
  12772.  
  12773.  
  12774.  
  12775.     INSERT            Set insert mode
  12776.  
  12777.       Command format: INSERT [ON|OF]
  12778.  
  12779.       Return values:  ON or  OFF dependent  on the  insert mode state after
  12780.                       the command is executed.
  12781.  
  12782.       Return codes:   RC_OK (0)
  12783.  
  12784.       Flip insert mode or set insert mode to on or off.
  12785.  
  12786.       Example:        INSERT ON
  12787.  
  12788.  
  12789.  
  12790.     ENTERINSERT       Set enter mode
  12791.  
  12792.       Command format: ENTERINSERT [ON|OF]
  12793.  
  12794.       Return values:  ON or OFF dependent on  the  enter  mode  state after
  12795.                       the command is executed.
  12796.  
  12797.       Return codes:   RC_OK (0)
  12798.  
  12799.       Flip enter mode or set enter mode to on or off.
  12800.  
  12801.       Example:        ENTERINSERT ON
  12802.  
  12803.  
  12804.  
  12805.   2 The CodeMan AREXX interface.
  12806.  
  12807.   The  CodeMan  AREXX  port  is  named  Comal.CodeMan.  The  AREXX commands
  12808.   accepted by the are:
  12809.  
  12810.  
  12811.     KILL              Remove the CodeMan process
  12812.  
  12813.       Command format: KILL
  12814.  
  12815.       Return values:  None
  12816.  
  12817.       Return codes:   RC_OK (0) if success
  12818.                       RC_WARN (5) if the command failed
  12819.  
  12820.       Example:        KILL
  12821.  
  12822.  
  12823.  
  12824.  
  12825.  
  12826.                                          225
  12827.  
  12828.  
  12829.  
  12830.  
  12831.  
  12832.     OPEN              Create new program buffer
  12833.  
  12834.       Command format: OPEN [MEMORY=size]
  12835.  
  12836.       Return values:  An address which is used to identify the buffer.
  12837.  
  12838.       Return codes:   RC_OK (0) if success
  12839.                       RC_ERROR (10) if the command failed
  12840.  
  12841.       A new program buffer is created. If MEMORY  is not  specified the de-
  12842.       fault value $8000 will be used.
  12843.  
  12844.       Example:        OPEN MEMORY=25000
  12845.  
  12846.  
  12847.     CLOSE             Close program buffer opened by the OPEN command.
  12848.  
  12849.       Command format: CLOSE ID=Id
  12850.  
  12851.       Return values:  None
  12852.  
  12853.       Return codes:   RC_OK (0) if success
  12854.                       RC_ERROR (10) if the program buffer was not found
  12855.  
  12856.       A  program  buffer  opened  by  the OPEN command is closed. The argu-
  12857.       ment Id is the address returned by the OPEN command.
  12858.  
  12859.       Example:        CLOSE ID=BUFFER
  12860.  
  12861.  
  12862.     CLEAR             Clear program buffer
  12863.  
  12864.       Command format: CLEAR ID=Id
  12865.  
  12866.       Return values:  None
  12867.  
  12868.       Return codes:   RC_OK (0) if success
  12869.                       RC_ERROR (10) if the program buffer was not found
  12870.  
  12871.       The argument Id is the address returned by the OPEN command.
  12872.  
  12873.       Example:        CLEAR ID=BUFFER
  12874.  
  12875.  
  12876.     LOAD              Load program file into program buffer
  12877.  
  12878.       Command format: LOAD ID=Id FILENAME=Name
  12879.  
  12880.       Return values:  None
  12881.  
  12882.  
  12883.                                          226
  12884.  
  12885.  
  12886.  
  12887.  
  12888.  
  12889.       Return codes:   RC_OK (0) if success
  12890.                       RC_ERROR (10) if the buffer or file was not found
  12891.  
  12892.       A program stored as a code  file if  loaded. The  argument Id  is the
  12893.       address returned by the OPEN command.
  12894.  
  12895.       Example:        LOAD ID=BUFFER FILENAME=MyFile
  12896.  
  12897.  
  12898.     SAVE              Save program buffer as a code program file.
  12899.  
  12900.       Command format: SAVE ID=Id FILENAME=Name
  12901.  
  12902.       Return values:  None
  12903.  
  12904.       Return codes:   RC_OK (0) if success
  12905.                       RC_ERROR (10) if the no buffer or write error
  12906.  
  12907.       The content of the program buffer is stored as a code file. The argu-
  12908.       ment Id is the address returned by the OPEN command.
  12909.  
  12910.       Example:        SAVE ID=BUFFER FILENAME=MyFile
  12911.  
  12912.  
  12913.     MAKECODE          Generate intermediate code
  12914.  
  12915.       Command format: MAKECODE ID=Id ProgramLine
  12916.  
  12917.       Return values:  Address of the generated code.
  12918.  
  12919.       Return codes:   RC_OK (0) if success
  12920.                       RC_ERROR (10) else
  12921.  
  12922.       Intermediate code for the ASCII program line specified as argument is
  12923.       generated. The address of the generated code is returned.
  12924.  
  12925.       Example:        MAKECODE ID=BUFFER 'IF Alfa=7 THEN'
  12926.  
  12927.  
  12928.     MAKEDIREC         Generate intermediate code for direct command
  12929.  
  12930.       Command format: MAKEDIREC ID=Id ProgramLine
  12931.  
  12932.       Return values:  Address of the generated code.
  12933.  
  12934.       Return codes:   RC_OK (0) if success
  12935.                       RC_ERROR (10) else
  12936.  
  12937.       Intermediate code for the command specified as argument is generated.
  12938.       The address of the generated code is returned.
  12939.  
  12940.                                          227
  12941.  
  12942.  
  12943.  
  12944.  
  12945.  
  12946.  
  12947.       Example:        MAKEDIREC ID=BUFFER 'PRINT sin(1)'
  12948.  
  12949.  
  12950.     MAKEASCII         Change intermediate code to ASCII
  12951.  
  12952.       Command format: MAKECODE ID=Id
  12953.  
  12954.       Return values:  Address of the generated ASCII line.
  12955.  
  12956.       Return codes:   RC_OK (0) if success
  12957.                       RC_ERROR (10) else
  12958.  
  12959.       An ASCII text line for the current buffer line is generated. The address
  12960.       of the generated line is returned.
  12961.  
  12962.       Example:        MAKEASCII ID=BUFFER
  12963.  
  12964.  
  12965.     INSERT            Insert code in the program buffer
  12966.  
  12967.       Command format: INSERT ID=Id
  12968.  
  12969.       Return values:  None.
  12970.  
  12971.       Return codes:   RC_OK (0) if success
  12972.                       RC_ERROR (10) else
  12973.  
  12974.       The  code  generated  by  the  last MAKECODE or MAKEDIREC is inserted
  12975.       at the current position of the buffer pointer.
  12976.  
  12977.       Example:        INSERT ID=BUFFER
  12978.  
  12979.  
  12980.     DELETE            Delete the current buffer line
  12981.  
  12982.       Command format: DELETE ID=Id
  12983.  
  12984.       Return values:  None
  12985.  
  12986.       Return codes:   RC_OK (0) if success
  12987.                       RC_ERROR (10) else
  12988.  
  12989.       Example:        DELETE ID=BUFFER
  12990.  
  12991.  
  12992.     REPLACE           Replace code in the program buffer
  12993.  
  12994.       Command format: REPLACE ID=Id
  12995.  
  12996.  
  12997.                                          228
  12998.  
  12999.  
  13000.  
  13001.  
  13002.  
  13003.       Return values:  None.
  13004.  
  13005.       Return codes:   RC_OK (0) if success
  13006.                       RC_ERROR (10) else
  13007.  
  13008.       The current line in the program buffer is replaced by the code genera-
  13009.       ted by the last MAKECODE or MAKEDIREC.
  13010.  
  13011.       Example:        REPLACE ID=BUFFER
  13012.  
  13013.  
  13014.     POSITION          Move buffer pointer to specified position
  13015.  
  13016.       Command format: POSITION ID=Id <place>  where place is:
  13017.                         SOF start of file
  13018.                         EOF end of file
  13019.  
  13020.       Return values:  None
  13021.  
  13022.       Return codes:   RC_OK (0) if success
  13023.                       RC_ERROR (10) else
  13024.  
  13025.       Example.        POSITION ID=BUFFER SOF
  13026.  
  13027.  
  13028.     LINE              Move buffer pointer up/down specified number of lines
  13029.  
  13030.       Command format: LINE ID=Id <number>
  13031.  
  13032.       Return values:  None.
  13033.  
  13034.       Return codes:   RC_OK (0) if success
  13035.                       RC_WARN (5) if border of text
  13036.                       RC_ERROR (10) else
  13037.  
  13038.       Example:        LINE ID=BUFFER -5 /* Move 5 lines down  */
  13039.  
  13040.  
  13041.  
  13042.  
  13043.   3 The interpreter AREXX interface.
  13044.  
  13045.   For each  interpreter opened  a separate  process is started with its own
  13046.   AREXX port. The name of the port is  Comal.Interpreter.<id>. For  the in-
  13047.   terpreters opened  by the  editor the  <Id> if 001, 002 etc. For instance
  13048.   Comal.Interpreter.001.
  13049.  
  13050.   Only two AREXX commands are accepted by the interpreter:
  13051.  
  13052.  
  13053.  
  13054.                                          229
  13055.  
  13056.  
  13057.  
  13058.  
  13059.  
  13060.     KILL              Remove the Interpreter master
  13061.  
  13062.       Command format: KILL
  13063.  
  13064.       Return values:  None
  13065.  
  13066.       Return codes:   RC_OK (0) if success
  13067.                       RC_WARN (5) if the command failed
  13068.  
  13069.       Example:        KILL
  13070.  
  13071.  
  13072.     EXECUTE           Load and execute program file.
  13073.  
  13074.       Command format:
  13075.           EXECUTE FILENAME=Name [WORKSPACE=Size] [STACK=Size]
  13076.  
  13077.       Return values:  None
  13078.  
  13079.       Return codes:   RC_OK (0) if success
  13080.                       RC_WARN (10) else
  13081.  
  13082.       A program  stored on  disk in  code form  is loaded  and executed. If
  13083.       WORKSPACE is  not specified  the default size $8000 is used. If STACK
  13084.       is not specified the default stack size $4000 is used.
  13085.  
  13086.       Example:        EXECUTE FILENAME=Comal:Programs/GraphDemo
  13087.  
  13088.  
  13089.  
  13090.   4 An AREXX script example.
  13091.  
  13092.   The following script will cut off a marked block and save it on disk as a
  13093.   code file. This is done by opening a separate program buffer and move the
  13094.   block into this buffer line by line.
  13095.  
  13096.  
  13097.     /* Save block as code file  */
  13098.  
  13099.     OPTIONS RESULTS
  13100.     'BLOCKSIZE'
  13101.     IF RC > 0 
  13102.       THEN DO
  13103.         OPTIONS
  13104.         WRITESTATUS 'No block marked'
  13105.       END
  13106.       ELSE DO
  13107.         BlockSize = RESULT
  13108.         IF ARG() = 0
  13109.         THEN DO
  13110.  
  13111.                                          230
  13112.  
  13113.  
  13114.  
  13115.  
  13116.  
  13117.           'GETFILE'
  13118.           File = RESULT
  13119.         END
  13120.         ELSE DO
  13121.           File = ARG(1)
  13122.         END
  13123.         IF RC = 0
  13124.         THEN DO
  13125.           'BLOCK'
  13126.           IF BlockSize < 0
  13127.           THEN DO
  13128.             OPTIONS
  13129.             'LINE' BlockSize
  13130.             BlockLen = -BlockSize+1;
  13131.             BlockSize =0
  13132.           END
  13133.           ELSE DO
  13134.             BlockLen = BlockSize+1;
  13135.             BlockSize = -BlockSize
  13136.           END
  13137.           address 'Comal.CodeMan'
  13138.           OPTIONS RESULTS
  13139.           'OPEN'
  13140.           ID = RESULT
  13141.           DO BlockLen
  13142.             address
  13143.             OPTIONS RESULTS
  13144.             'GETTEXT'
  13145.             Line = RESULT
  13146.             'CURSOR DOWN'
  13147.             address
  13148.             OPTIONS
  13149.             MAKECODE 'ID ' ID Line
  13150.             INSERT 'ID ' ID
  13151.             'LINE ID ' ID 1
  13152.           END
  13153.           'SAVE ID ' ID FILENAME File
  13154.           'CLOSE' 'ID ' ID
  13155.           address
  13156.           'LINE' BlockSize
  13157.         END
  13158.       END
  13159.  
  13160.  
  13161.  
  13162.  
  13163.  
  13164.  
  13165.  
  13166.  
  13167.  
  13168.                                          231
  13169.  
  13170.  
  13171.  
  13172.  
  13173.  
  13174.   VIII. COMAL IO DEVICES
  13175.  
  13176.  
  13177.   1 What is a Comal device?
  13178.  
  13179.   A Comal IO device is a sort of a file with a predefined name. The name of
  13180.   a Comal device always ends with a colon (:). At the start of the Comal sy-
  13181.   stem three Comal devices are defined:
  13182.  
  13183.     "ds:"   the standard IO window
  13184.     "kb:"   the keyboard attached the the IO window
  13185.     "lp:"   the printer
  13186.  
  13187.  
  13188.   These device names can  be used  in a  OPEN FILE  satements and  a SELECT
  13189.   statements.
  13190.  
  13191.   Example:
  13192.  
  13193.     OPEN FILE 1,"ds:",WRITE
  13194.     SELECT OUTPUT "lp:"
  13195.  
  13196.  
  13197.   The devices  are primariy  intented for  use in SELECT statements. At the
  13198.   start of a program execution implicite
  13199.  
  13200.     SELECT OUTPUT "ds:"
  13201.  
  13202.   and
  13203.  
  13204.     SELECT INPUT "kb:"
  13205.  
  13206.   are executed.
  13207.  
  13208.  
  13209.   2 Making new devices.
  13210.  
  13211.   It is possible to add new devices or to replace one of the predefined devi-
  13212.   ces. A  new device  is added by calling the internal Comal procedure Add-
  13213.   ComalDevice (found in the module SystemCode).
  13214.  
  13215.   All devices are linked together in a list and AddComalDevice links the new
  13216.   device into  the start of this list. Thus adding a device having the same
  13217.   name as an excisting device will in fact replace that device.
  13218.  
  13219.   A device is removed from the list by calling RemComalDevice.
  13220.  
  13221.   The procedure AddComalDevice is called with an initialized device structure
  13222.   that completely describes the device:
  13223.  
  13224.  
  13225.                                          232
  13226.  
  13227.  
  13228.  
  13229.  
  13230.  
  13231.     STRUC IoDevice
  13232.       DIM NextDevice OF POINTER TO IoDevice
  13233.       DIM Name OF ULONG
  13234.       DIM Type OF USHORT
  13235.       DIM Reserved OF SHORT
  13236.       DIM Open OF ULONG
  13237.       DIM Close OF ULONG
  13238.       DIM Read OF ULONG
  13239.       DIM Write OF ULONG
  13240.       DIM ReadLn OF ULONG
  13241.       DIM WriteLn OF ULONG
  13242.       DIM Scan OF ULONG
  13243.       DIM GetStrmPtr OF ULONG
  13244.       DIM SetStrmPtr OF ULONG
  13245.       DIM StreamErr OF ULONG
  13246.     ENDSTRUC IoDevice
  13247.  
  13248.  
  13249.   Field desription:
  13250.  
  13251.     NextDevice
  13252.  
  13253.       A pointer to the next device in the list of devices. Set by the Comal
  13254.       system.
  13255.  
  13256.  
  13257.     Name
  13258.  
  13259.       A pointer to the name of the device. Must end with a colon (:).
  13260.  
  13261.  
  13262.     Type
  13263.  
  13264.       The possible device types are:
  13265.  
  13266.         SEQ_DEVICE (0)  sequential device (for instance a printer)
  13267.         CRT_DEVICE (1)  used by windows
  13268.         KBD_DEVICE (2)  keyboard
  13269.         RBF_DEVICE (3)  random access device
  13270.  
  13271.  
  13272.     Open          open device
  13273.  
  13274.       An address of an open procedure of the form:
  13275.  
  13276.         FUNC Open(Name OF ULONG,Mode OF USHORT,REF Eof OF SHORT)
  13277.  
  13278.       where
  13279.  
  13280.         Name is a null terminated string  of characters.  The start  of the
  13281.  
  13282.                                          233
  13283.  
  13284.  
  13285.  
  13286.  
  13287.  
  13288.           string is  the device  name. The  characters after  the colon are
  13289.           transfered from the name in  the  OPEN  or  SELECT  statement and
  13290.           can be used to specify special parameters for the device (for in-
  13291.           stance: SELECT OUTPUT "sp: baud=1200").
  13292.  
  13293.  
  13294.         Mode is one or more of the following BITORed together:
  13295.  
  13296.           ACCESS_READ (1)   read only device (such as a keyboard)
  13297.           ACCESS_WRITE (2)  write only device (such as a printer)
  13298.           ACCESS_NEW (4)    delete excisting (if window for instance)
  13299.  
  13300.       At return the function sets the parameter Eof (end of file) to TRUE or
  13301.       FALSE  and  returns  an  ULONG  which is used to indentify the device
  13302.       (zero means error).
  13303.  
  13304.  
  13305.     Close         close the device
  13306.  
  13307.       An address of a procedure of the form:
  13308.  
  13309.         PROC Close(Id OF ULONG)
  13310.  
  13311.  
  13312.       The procedure is called when a  CLOSE statement  is executed  or when
  13313.       another device is selected in a SELECT statement. Id is the identifier
  13314.       returned by the open procedure.
  13315.  
  13316.       The procedure should not necessarily close the device. If for instance
  13317.       the device  is a  CRT_DEVICE like  "ds:" it is not smart to close the
  13318.       window each time another device is selected by the SELECT statement.
  13319.  
  13320.  
  13321.     Read          read a block of bytes
  13322.  
  13323.       An address of a function of the form:
  13324.  
  13325.         FUNC Read(Id,Data,REF MaxBytes,REF BreakMask) OF SHORT
  13326.  
  13327.       where
  13328.  
  13329.         Id OF ULONG is the device identifier returned by OPEN.
  13330.         Data OF ULONG is the address of a read buffer.
  13331.         MaxByte OF LONG is the number of bytes to read.
  13332.         BreakMask OF ULONG is a  mask  of  signals  that  should  break the
  13333.           reading. Not all devices supports this facility.
  13334.  
  13335.       Before return the routine must set the actual number of bytes read in
  13336.       MaxBytes and then return -1 (if error), 0 if OK or 1 if end of stream
  13337.       was reached.
  13338.  
  13339.                                          234
  13340.  
  13341.  
  13342.  
  13343.  
  13344.  
  13345.  
  13346.  
  13347.     Write         write a block of bytes
  13348.  
  13349.       An address of a function of the form
  13350.  
  13351.         FUNC Write(Id,Data,Length) OF SHORT
  13352.  
  13353.       where
  13354.  
  13355.         Id OF ULONG is the device identifier returned by OPEN.
  13356.         Data OF ULONG is the address of the data to write.
  13357.         Length OF LONG is the number of bytes to write.
  13358.  
  13359.       Before return the routine must set the actual number of bytes written
  13360.       in Length and then return TRUE (1) if OK or FALSE (0) if error.
  13361.  
  13362.       If this field is set for a KBD_DEVICE, guide texts in INPUT statements
  13363.       are sent to this function.
  13364.  
  13365.  
  13366.     ReadLn        read one line
  13367.  
  13368.       An address of a function of the form
  13369.  
  13370.         FUNC ReadLn(Id,Data,REF MaxLength) OF SHORT
  13371.  
  13372.       where
  13373.  
  13374.         Id OF ULONG is the device identifier returned by OPEN.
  13375.         Data OF ULONG is the address of a read buffer.
  13376.         MaxByte OF LONG is the maximal number of bytes to read.
  13377.  
  13378.       The routine reads characters until a line end character is read or Max-
  13379.       Bytes characters are read. The routine is responsible for editing during
  13380.       the input (if CRT_DEVICE).
  13381.  
  13382.       Before return the routine must set the actual number of bytes read in
  13383.       MaxBytes (The line end character not included) and then return -1 (if
  13384.       error), 0 if OK or 1 if end of stream was reached.
  13385.  
  13386.  
  13387.     WriteLn         write one line
  13388.  
  13389.       An address of a function of the form
  13390.  
  13391.         FUNC WriteLn(Id,Line,Length) OF SHORT
  13392.  
  13393.       where
  13394.  
  13395.  
  13396.                                          235
  13397.  
  13398.  
  13399.  
  13400.  
  13401.  
  13402.         Id OF ULONG is the device identifier returned by OPEN.
  13403.         Line OF ULONG is the address of the line to write.
  13404.         Length OF LONG is the length of the line to write.
  13405.  
  13406.       The routine must terminate by writing a line termination character to
  13407.       the device. Before return the routines must set the actual  number of
  13408.       bytes written  in Length  and then return TRUE (1) if OK or FALSE (0)
  13409.       if error.
  13410.  
  13411.  
  13412.     Scan          scan the device
  13413.  
  13414.       An address of a function of the form
  13415.  
  13416.         FUNC Scan(Id,Data,REF Length) OF SHORT
  13417.  
  13418.       where
  13419.  
  13420.         Id OF ULONG is the device identifier returned by OPEN.
  13421.         Data OF ULONG is the address of a read buffer.
  13422.         Length OF LONG is the length of the read buffer.
  13423.  
  13424.       The function should test if there are "characters" ready in the device.
  13425.       If this is the case ot should return the first "character". Otherwise it
  13426.       should return without reading  any characters.  A "character"  may be
  13427.       more than  one byte.  A keyboard  for instance  returns more than one
  13428.       byte if a function key is pressed.
  13429.  
  13430.       Before return the routine must set the actual number of bytes read in
  13431.       Length and  then return  -1 (if error), 0 if OK or 1 if end of stream
  13432.       was reached.
  13433.  
  13434.  
  13435.     Get           get position of the stream pointer
  13436.  
  13437.       Get is the address of a function. The format of this function depends
  13438.       on the device type.
  13439.  
  13440.         CRT_DEVICE:   FUNC Get(Id,REF Row, REF Col) OF SHORT
  13441.  
  13442.           where
  13443.  
  13444.             Id OF ULONG is the device identifier.
  13445.             Row OF SHORT is used to return row number of the cursor
  13446.             Col OF SHORT is used to return column number of the cursor
  13447.  
  13448.         RBF_DEVICE:   FUNC Get(Id,REF Offset) OF SHORT
  13449.  
  13450.           where
  13451.  
  13452.  
  13453.                                          236
  13454.  
  13455.  
  13456.  
  13457.  
  13458.  
  13459.             Id OF ULONG is the device identifier.
  13460.             Offset  OF  LONG  is  used  to return the current offset of the
  13461.               stream pointer.
  13462.  
  13463.       Other devices should set these fields to zero. For both functions the
  13464.       return value is TRUE if operation succeded and otherwise FALSE.
  13465.  
  13466.  
  13467.     Set           set position of the stream pointer
  13468.  
  13469.       Set is the address of a function. The format of this function depends
  13470.       on the device type.
  13471.  
  13472.         CRT_DEVICE:
  13473.  
  13474.             FUNC Set(Id,Row,Col) OF SHORT
  13475.  
  13476.           where
  13477.  
  13478.             Id OF ULONG is the device identifier.
  13479.             Row OF SHORT is the new row number of the cursor
  13480.             Col OF SHORT is the new column number of the cursor
  13481.  
  13482.  
  13483.         RBF_DEVICE:
  13484.  
  13485.             FUNC Get(Id,REF Offset) OF SHORT
  13486.  
  13487.           where
  13488.  
  13489.             Id OF ULONG is the device identifier.
  13490.             Offset OF LONG is the new offset of the stream pointer.
  13491.  
  13492.       Other devices should set these fields to zero. For both functions the
  13493.       return value is TRUE if operation succeded and otherwise FALSE.
  13494.  
  13495.  
  13496.     StreamErr
  13497.  
  13498.       For the time being not used. Set to zero.
  13499.  
  13500.  
  13501.   The fields  Name, Type,  Open, Close,  Get (CRT and RBF) and Set (CRT and
  13502.   RBF) must be set. Other fields may be set to zero if the device  does not
  13503.   support the function.
  13504.  
  13505.  
  13506.   The following module adds a serial device "sp:" to the list of Comal devices:
  13507.  
  13508.  
  13509.  
  13510.                                          237
  13511.  
  13512.  
  13513.  
  13514.  
  13515.  
  13516.   // Serial device "sp:"
  13517.  
  13518.   MODULE SerialDevice
  13519.  
  13520.     USE System
  13521.     USE SystemCode
  13522.     USE PortObjects
  13523.     USE IoObjects
  13524.     USE ExecLibrary
  13525.  
  13526.     STRUC IOTArray
  13527.       DIM TermArray0 OF ULONG
  13528.       DIM TermArray1 OF ULONG
  13529.     ENDSTRUC IOTArray
  13530.  
  13531.     STRUC IOExtSer  // Standard IO request to serial.device
  13532.       INHERIT IOStdReq             // Standard IO-request
  13533.       DIM io_CtrlChar OF ULONG     // xON, xOFF, INQ, ACK
  13534.       DIM io_RBufLen OF ULONG      // length of read buffer
  13535.       DIM io_ExtFlags OF ULONG     // Not used
  13536.       DIM io_Baud OF ULONG         // Baud rate
  13537.       DIM io_BrkTime OF ULONG      // duration of break signal in micros
  13538.       DIM io_TermArray OF IOTArray // Termination characters
  13539.       DIM io_ReadLen OF UBYTE      // Bits per read character
  13540.       DIM io_WriteLen OF UBYTE     // Bits per write character
  13541.       DIM io_StopBits OF UBYTE     // Number of stop bits
  13542.       DIM io_SerFlags OF UBYTE     // Flags set by serial device
  13543.       DIM io_Status OF USHORT
  13544.     ENDSTRUC IOExtSer
  13545.  
  13546.     STRUC IoDevice
  13547.       DIM NextDevice OF POINTER TO IoDevice
  13548.       DIM Name OF ULONG       // Pointer to device name 'sp:'
  13549.       DIM Type OF USHORT      // Type of device
  13550.       DIM Reserved OF SHORT
  13551.       DIM Open OF ULONG
  13552.       DIM Close OF ULONG
  13553.       DIM Read OF ULONG
  13554.       DIM Write OF ULONG
  13555.       DIM ReadLn OF ULONG
  13556.       DIM WriteLn OF ULONG
  13557.       DIM Scan OF ULONG
  13558.       DIM GetStrmPtr OF ULONG
  13559.       DIM SetStrmPtr OF ULONG
  13560.       DIM StreamErr OF ULONG
  13561.     ENDSTRUC IoDevice
  13562.  
  13563.     DIM CMD_READ OF SHORT
  13564.     DIM CMD_WRITE OF SHORT
  13565.     DIM CMD_NONSTD OF SHORT
  13566.  
  13567.                                          238
  13568.  
  13569.  
  13570.  
  13571.  
  13572.  
  13573.  
  13574.     CMD_READ:=2
  13575.     CMD_WRITE:=3
  13576.     CMD_NONSTD:=9
  13577.  
  13578.     DIM SerReq OF POINTER TO IOExtSer
  13579.     DIM ReplyPort OF POINTER TO MsgPort
  13580.     DIM DevOpen OF BOOL
  13581.     DIM SerDevice OF IoDevice
  13582.     DIM SerDevName$ OF 3
  13583.  
  13584.     SerDevName$:="sp:"
  13585.     SerDevice.Name:=ADR(SerDevName$)
  13586.     SerDevice.Type:=0         // Sequential device
  13587.     SerDevice.Open:=ADR(SerOpen(,,))
  13588.     SerDevice.Close:=ADR(SerClose())
  13589.     SerDevice.Read:=ADR(SerRead(,,,))
  13590.     SerDevice.Write:=ADR(SerWrite(,,))
  13591.     SerDevice.ReadLn:=ADR(SerReadLn(,,))
  13592.     SerDevice.WriteLn:=ADR(SerWriteLn(,,))
  13593.     AddComalDevice(ADR(SerDevice))
  13594.  
  13595.     FUNC SerOpen(Name OF ULONG,Mode OF USHORT,REF Eof OF SHORT)
  13596.                                                           OF ULONG
  13597.       ALLOCATE(SerReq,MEMF_PUBLIC)
  13598.       ALLOCATE(ReplyPort,MEMF_PUBLIC)
  13599.       SerReq@.mn_ReplyPort:=ReplyPort
  13600.  
  13601.       // Open serial.device'
  13602.       IF OpenDevice("serial.device",0,SerReq,0) THEN
  13603.         DEALLOCATE(SerReq)
  13604.         RETURN 0
  13605.       ENDIF
  13606.       DevOpen:=TRUE
  13607.  
  13608.       // Set TermArray
  13609.       SerReq@.io_Command:=CMD_NONSTD+2
  13610.       SerReq@.io_TermArray.TermArray0:=$1C0A0A0A
  13611.       SerReq@.io_TermArray.TermArray1:=$0A0A0A0A
  13612.       SerReq@.Do  // Set TermArray
  13613.  
  13614.       Eof:=FALSE
  13615.       RETURN $FFFFFFFF
  13616.     ENDFUNC SerOpen
  13617.  
  13618.     PROC SerClose(Id OF ULONG)
  13619.       IF DevOpen THEN
  13620.         SerReq@.Abort
  13621.         dummy:=SerReq@.mn_ReplyPort@.Get
  13622.         CloseDevice(SerReq)
  13623.  
  13624.                                          239
  13625.  
  13626.  
  13627.  
  13628.  
  13629.  
  13630.         DEALLOCATE(SerReq)
  13631.         DEALLOCATE(ReplyPort)
  13632.         DevOpen:=FALSE
  13633.       ENDIF
  13634.     ENDPROC SerClose
  13635.  
  13636.     FUNC SerRead(Id OF ULONG,Buffer OF ULONG,REF MaxLen OF, 
  13637.                  LONG,BreakMask OF ULONG) OF SHORT
  13638.       SerReq@.io_SerFlags:=SerReq@.io_SerFlags BITAND %10111111
  13639.       SerReq@.io_Command:=CMD_READ
  13640.       SerReq@.io_Length:=MaxLen
  13641.       SerReq@.io_Data:=Buffer
  13642.       SerReq@.Send               // Read data
  13643.       SerReq@.Wait
  13644.       MaxLen:=SerReq@.io_Actual  // Return number of bytes read
  13645.     ENDFUNC SerRead
  13646.  
  13647.     FUNC SerWrite(Id OF ULONG,Data OF ULONG,REF Length OF LONG)
  13648.                                                            OF BOOL
  13649.       SerReq@.io_Command:=CMD_WRITE
  13650.       SerReq@.io_Length:=Length
  13651.       SerReq@.io_Data:=Data
  13652.       SerReq@.Send               // Write data
  13653.       SerReq@.Wait
  13654.       IF SerReq@.io_Error THEN
  13655.         RETURN FALSE
  13656.       ELSE
  13657.         RETURN TRUE
  13658.       ENDIF
  13659.     ENDFUNC SerWrite
  13660.  
  13661.     FUNC SerReadLn(Id OF ULONG,Buffer OF ULONG,REF MaxLen OF LONG)
  13662.                                                              OF SHORT
  13663.       LOCAL Ptr OF POINTER TO UBYTE
  13664.  
  13665.       SerReq@.io_SerFlags:=SerReq@.io_SerFlags BITOR %01000000
  13666.       SerReq@.io_Command:=CMD_READ
  13667.       SerReq@.io_Length:=MaxLen
  13668.       SerReq@.io_Data:=Buffer
  13669.       SerReq@.Send                // Read data
  13670.       SerReq@.Wait
  13671.       IF SerReq@.io_Error THEN
  13672.         RETURN -1
  13673.       ENDIF
  13674.       Ptr:=ADR(Buffer)+SerReq@.io_Actual-1
  13675.       CASE Ptr@ OF
  13676.       WHEN $1C
  13677.         MaxLen:=SerReq@.io_Actual-1
  13678.         RETURN 1        // End of file
  13679.       WHEN $0A
  13680.  
  13681.                                          240
  13682.  
  13683.  
  13684.  
  13685.  
  13686.  
  13687.         MaxLen:=SerReq@.io_Actual-1
  13688.         RETURN 0
  13689.       OTHERWISE
  13690.         MaxLen:=SerReq@.io_Actual
  13691.         RETURN 0
  13692.       ENDCASE
  13693.     ENDFUNC SerReadLn
  13694.  
  13695.     FUNC SerWriteLn(Id OF ULONG,Data OF ULONG,REF Length OF LONG)
  13696.                                                            OF BOOL
  13697.       LOCAL ch OF UBYTE
  13698.  
  13699.       SerReq@.io_Command:=CMD_WRITE
  13700.       SerReq@.io_Length:=Length
  13701.       SerReq@.io_Data:=Data
  13702.       SerReq@.Send               // Write data
  13703.       SerReq@.Wait
  13704.       IF SerReq@.io_Error THEN
  13705.         RETURN FALSE
  13706.       ENDIF
  13707.       ch:=$0A
  13708.       SerReq@.io_Command:=CMD_WRITE
  13709.       SerReq@.io_Length:=1
  13710.       SerReq@.io_Data:=ADR(ch)
  13711.       SerReq@.Do     // Write LF
  13712.       IF SerReq@.io_Error THEN
  13713.         RETURN FALSE
  13714.       ELSE
  13715.         RETURN TRUE
  13716.       ENDIF
  13717.     ENDFUNC SerWriteLn
  13718.  
  13719.     PROC SerSignal(s OF LONG) SIGNAL
  13720.       CASE s OF
  13721.       WHEN SIG_CLOSE,SIG_DISCARD
  13722.         RemComalDevice(ADR(SerDevice))
  13723.       OTHERWISE
  13724.         // No action
  13725.       ENDCASE
  13726.     ENDPROC SerSignal
  13727.  
  13728.   ENDMODULE SerialDevice
  13729.  
  13730.  
  13731.   3 Making your own IO window.
  13732.  
  13733.   It is possible to replace the standard IO window opened by the interpreter
  13734.   by your own window. To see how this can be done it  is necessary  to know
  13735.   what is happening before a program is started.
  13736.  
  13737.  
  13738.                                          241
  13739.  
  13740.  
  13741.  
  13742.  
  13743.  
  13744.   When the  interpreter receives an execute command the IO is redirected to
  13745.   the IO port (see section V.2) and the standard console  device closes the
  13746.   execute window (if it is open). The console device closes the window when
  13747.   the signal SIG_CLEAR is send.
  13748.  
  13749.   Then the program is scanned and during this scanning process  all modules
  13750.   are loaded and are initialized by executing the initialization part of the
  13751.   module. A module can use this initialization to add a new "ds:" device and a
  13752.   new "kb:" device.
  13753.  
  13754.   After  the  scanning  an  implicite  SELECT OUTPUT "ds:" and an implicite
  13755.   SELECT INPUT "kb:" is executed. If a module has added a new  "ds:" device
  13756.   and a new "kb:" device these devices are put into the start of the device
  13757.   list and it will be these devices that are used by the SELECT statements.
  13758.  
  13759.   As a consequence your IO window will be opened and  the standard  IO win-
  13760.   dow will not be used.
  13761.  
  13762.   In the directory ModuleDev you will find an example of such a module pro-
  13763.   grammed in C (IoWindow.c and IoWindow.interface).
  13764.  
  13765.  
  13766.  
  13767.  
  13768.  
  13769.  
  13770.  
  13771.  
  13772.  
  13773.  
  13774.  
  13775.  
  13776.  
  13777.  
  13778.  
  13779.  
  13780.  
  13781.  
  13782.  
  13783.  
  13784.  
  13785.  
  13786.  
  13787.  
  13788.  
  13789.  
  13790.  
  13791.  
  13792.  
  13793.  
  13794.  
  13795.                                          242
  13796.  
  13797.  
  13798.  
  13799.  
  13800.  
  13801.   IX. MASHINE CODED MODULES
  13802.  
  13803.   Comal has been designed to be a modular language. It is possible to devide
  13804.   a project into several modules. These modules can be written in as different
  13805.   languages as assembler, C as well as the Comal language itself.
  13806.  
  13807.   Seen from the users of the modules there are no difference in the modules
  13808.   wether they are written in assembler, C or Comal. The routines in the mo-
  13809.   dules are called in exactly the same way. Very often a module is first writ-
  13810.   ten in Comal and then (if necessary) it is rewritten in C or even assembler.
  13811.  
  13812.   In chapter  III.9 development  of modules in Comal was described. In this
  13813.   chapter machine coded modules (written in C or assembler) will be descri-
  13814.   bed.
  13815.  
  13816.  
  13817.   1 The format of a mashine coded module.
  13818.  
  13819.   A mashine coded module consists of three parts:
  13820.  
  13821.     - the interface part
  13822.     - the initialization and signal routines
  13823.     - the routine part (procedures and functions in the module)
  13824.  
  13825.  
  13826.   In the following sections 1.1-1.3 the three parts are described. C program-
  13827.   mers do not need to read these sections.
  13828.  
  13829.  
  13830.   1.1 The interface part.
  13831.  
  13832.   In the interface part of a module all necessary informations about the ex-
  13833.   ported routines  are stored (the name and the address of the routine, the
  13834.   type of the routine and its parameters etc.).
  13835.  
  13836.   The interface part is a table of elements of the  form (described  in not
  13837.   100% correct C):
  13838.  
  13839.     struct NameTable NameTable[NumNames];
  13840.  
  13841.   where the NameTable structure is defined as
  13842.  
  13843.     struct NameTable
  13844.     {
  13845.       void *RoutineAddress;   /* The address of the routine           */
  13846.       struct ProcType *Type;  /* The address of the type descriptor   */
  13847.       char *RoutineName;      /* A pointer to the name of the routine */
  13848.     }
  13849.  
  13850.  
  13851.  
  13852.                                          243
  13853.  
  13854.  
  13855.  
  13856.  
  13857.  
  13858.   The information of the type of the routine is stored in a structure Proc-
  13859.   Type. Routines with the same type can use the same structure.
  13860.  
  13861.   The structure ProcType has the form:
  13862.  
  13863.     struct Param
  13864.     {
  13865.       UBYTE Flags;          /* Set to 0x80 if REF parameter       */
  13866.       BYTE  SecondaryType;  /* Set to zero                        */
  13867.       WORD  PrimaryType;    /* Parameter type (se include files)  */
  13868.     };
  13869.  
  13870.     struct ProcType
  13871.     {
  13872.       WORD TypeId;          /* PROC_ID or FUNC_ID                 */
  13873.       WORD ReturnType;      /* Return type (FUNC) or zero (PROC)  */
  13874.       WORD *TypeDescriptor; /* Set to zero                        */
  13875.       UWORD Flags;
  13876.       UBYTE StackUse1;      /* Stack use of type descriptors      */
  13877.       UBYTE StackUse0;      /* Primary parameter stack use        */
  13878.       UWORD NumPar;         /* Number of formal parameters        */
  13879.       struct Param Param[NumPar];
  13880.     };
  13881.  
  13882.   Set Flags to 0x0001 if it is a string function returning a C string (null ter-
  13883.   minated ASCII string).
  13884.  
  13885.   The stack  use are the number of bytes used to transfer the parameters on
  13886.   the stack. The secondary stack is used to transfer the address of  a type
  13887.   descriptor for  structured types  (ARRAY, FUNC  and PROC) and REF parame-
  13888.   ters. 
  13889.  
  13890.  
  13891.   1.2 The initialization and signal routines.
  13892.  
  13893.   The initialization routine is the very first mashine instructions in the mo-
  13894.   dule. It is a function with the C format:
  13895.  
  13896.     short Init(struct ComalStruc *ComalStruc,struct Module *Module)
  13897.  
  13898.  
  13899.   This means  that the addresses of the ComalStruc and the module structure
  13900.   for the module in question are pushed onto the stack (as two  long words)
  13901.   before a call is made to the first instruction of the module.
  13902.  
  13903.   The initialization  routine should as a minimum fill the module structure
  13904.   with the address of the name table and  the number  of names  in the name
  13905.   table and then return the status code (in D0.W). Zero is the OK code.
  13906.  
  13907.  
  13908.  
  13909.                                          244
  13910.  
  13911.  
  13912.  
  13913.  
  13914.  
  13915.   Very often an initialization routine also stores the address of the Comal-
  13916.   Struc for later use.
  13917.  
  13918.   A signal routine is a procedure with the C format:
  13919.  
  13920.     void signal(short SignalNum)
  13921.  
  13922.  
  13923.   To tell the comal system that there is a signal routine, the address of the
  13924.   routine must be placed in the module structure by the initialization routine.
  13925.   Otherwise there are no difference between a signal routine in a Comal mo-
  13926.   dule and a mashine coded module. The same signal numbers are send.
  13927.  
  13928.   All routines, including the initialization routine and the signal routine, may
  13929.   use registers D0-D1/A0/A1. The content of all other registers must be re-
  13930.   stored before a return.
  13931.  
  13932.  
  13933.   1.3 The routine part.
  13934.  
  13935.   Procedures and  functions that  are to be exported from the module (those
  13936.   referenced in the name table) must have the form used by most C compilers
  13937.   (for instance SAS/C ver. 5.xx).
  13938.  
  13939.   When a procedure or a function is called from Comal, the actual parameters
  13940.   are pushed onto the stack.
  13941.  
  13942.   Float value parameters are pushed as two long words. Value parameters for
  13943.   the integer types are pushed as one long word (byte and short integers are
  13944.   sign extended before they are pushed).
  13945.  
  13946.   Text values are transfered as an address to the text value that is null ter-
  13947.   minated.
  13948.  
  13949.   Parameters  of  the  type  STRUC,  ARRAY,  PROC  and  FUNC as well as REF
  13950.   parameters of any kind are pushed as addresses.
  13951.  
  13952.   Values returned by functions are passed back in register D0 (D0 and D1 if
  13953.   float).
  13954.  
  13955.   All routines  may use registers D0-D1/A0/A1. The content of all other re-
  13956.   gisters must be restored before a return.
  13957.  
  13958.  
  13959.   2 An assembler programmed module.
  13960.  
  13961.   Let us as an example show  how a  module is  programmed in  assembler. We
  13962.   are going  to make a module containing the following procedures and func-
  13963.   tions:
  13964.  
  13965.  
  13966.                                          245
  13967.  
  13968.  
  13969.  
  13970.  
  13971.  
  13972.     FUNC Even(i OF LONG) OF SHORT
  13973.     FUNC Hex$(i OF ULONG)
  13974.     PROC Capital(REF t$)
  13975.  
  13976.  
  13977.   The interface part contains a name table of three elements
  13978.  
  13979.  
  13980.   NameTable:     DC.L    CapitalName      * Name of procedure
  13981.                  DC.L    CapitalType      * Type descriptor
  13982.                  DC.L    Capital          * Routine address
  13983.  
  13984.                  DC.L    HexName
  13985.                  DC.L    HexType
  13986.                  DC.L    Hex
  13987.  
  13988.                  DC.L    EvenName
  13989.                  DC.L    EvenType
  13990.                  DC.L    Even
  13991.  
  13992.   CapitalName:   DC.B    'Capital',0
  13993.   HexName:       DC.B    'Hex$',0
  13994.   EvenName:      DC.B    'Even',0
  13995.  
  13996.  
  13997.   and type descriptors for each function/procedure:
  13998.  
  13999.  
  14000.   CapitalType:   DC.W    ProcTypeId       * Procedure
  14001.                  DC.W    0                * No return value
  14002.                  DC.L    0                * Always set to zero
  14003.                  DC.W    $0000            * No flags
  14004.                  DC.B    4                * Sec. stack (REF)
  14005.                  DC.B    4                * Address = 4 bytes
  14006.                  DC.W    1                * One parameter
  14007.                  DC.B    $80              * REF parameter
  14008.                  DC.B    0                * Always zero
  14009.                  DC.W    StringTypeId     * Parameter type
  14010.  
  14011.   HexType:       DC.W    FuncTypeId       * Function
  14012.                  DC.W    StringTypeId     * Return value
  14013.                  DC.L    0
  14014.                  DC.W    $0001            * C string is returned
  14015.                  DC.B    0                * No sec. stack use
  14016.                  DC.B    4                * Int paramter = 4 bytes
  14017.                  DC.W    1                * One parameter
  14018.                  DC.B    $00              * Value parameter
  14019.                  DC.B    0
  14020.                  DC.W    UlongTypeId      * Parameter type
  14021.  
  14022.  
  14023.                                          246
  14024.  
  14025.  
  14026.  
  14027.  
  14028.  
  14029.   EvenType:      DC.W    FuncTypeId       * Function
  14030.                  DC.W    ShortTypeId      * Return type
  14031.                  DC.L    0
  14032.                  DC.W    $0000            * No flags
  14033.                  DC.B    0                * No sec. stack use
  14034.                  DC.B    4                * Int parameter = 4 bytes
  14035.                  DC.W    1                * One parameter
  14036.                  DC.B    $00              * Value parameter
  14037.                  DC.B    0
  14038.                  DC.W    LongTypeId       * Parameter type
  14039.  
  14040.  
  14041.   The initialization routine is very simple:
  14042.  
  14043.   Init:    MOVE.L  4(A7),ComalStruc         * Store ComalStruc addr
  14044.            MOVE.L  8(A7),A0
  14045.            MOVE.L  #NameTable,MS_Names(A0)  * Name table address
  14046.            MOVE.W  #3,MS_NumName(A0)        * Number of names
  14047.            MOVEQ   #0,D0                    * Initialization OK
  14048.            RTS
  14049.  
  14050.  
  14051.   The complete source for the module looks like:
  14052.  
  14053.  
  14054.   ; Module Demo
  14055.  
  14056.            include 'Comal.i'
  14057.  
  14058.            SECTION DemoCode,CODE
  14059.            CNOP    0,2
  14060.  
  14061.   Start:   MOVE.L  4(A7),ComalStruc         * Store ComalStruc addr
  14062.            MOVE.L  8(A7),A0
  14063.            MOVE.L  #NameTable,MS_Names(A0)  * Name table address
  14064.            MOVE.W  #3,MS_NumName(A0)        * Number of names
  14065.            MOVEQ   #0,D0                    * Initialization OK
  14066.            RTS
  14067.  
  14068.   Capital: MOVE.L  4(A7),A1                 * Get string address
  14069.   CapLoop: MOVE.B  (A1)+,D0                 * Get next character
  14070.            BEQ.S   CapEnd                   * Return if zero
  14071.            CMP.B   #'a',D0                  * Small letter?
  14072.            BCS     CapLoop                  * No -> loop
  14073.            CMP.B   #'z',D0
  14074.            BHI     CapLoop
  14075.            BCLR    #5,-1(A1)                * Change to capital
  14076.            BRA     CapLoop
  14077.   CapEnd:  RTS
  14078.  
  14079.  
  14080.                                          247
  14081.  
  14082.  
  14083.  
  14084.  
  14085.  
  14086.   Hex:     MOVE.L  ComalStruc,A0            * Get address of ComalStruc
  14087.            MOVE.L  CS_CurrWorkBottom(A0),A1 * .. and work space start
  14088.            MOVE.L  A1,D0                    * Set as return value
  14089.            LEA     10(A1),A1                * Reserve 10 bytes
  14090.            MOVE.L  A1,CS_CurrWorkBottom(A0) * Set new bottom
  14091.            MOVE.L  D0,A1                    * Get start of string
  14092.            MOVE.B  #'$',(A1)+               * Start with hex specifier
  14093.            MOVE.B  #'0',(A1)+
  14094.            MOVE.L  4(A7),D1                 * Number to D1
  14095.            BEQ.S   HexEnd                   * Return if zero
  14096.            MOVEM.L D2/D3,-(A7)              * Store registers
  14097.            SUBQ.L  #1,A1                    * Point after $
  14098.            MOVEQ   #8,D3
  14099.            LEA     Digits(PC),A0         
  14100.   HxLoop1: ROL.L   #4,D1                    * Find first non zero digit
  14101.            SUBQ.W  #1,D3
  14102.            MOVE.W  D1,D2
  14103.            AND.W   #$000F,D2
  14104.            BEQ     HxLoop1
  14105.   HxLoop2: MOVE.B  0(A0,D2.W),(A1)+         * Nex hex digit to buffer
  14106.            ROL.L   #4,D1
  14107.            MOVE.W  D1,D2
  14108.            AND.W   #$000F,D2
  14109.            DBRA    D3,HxLoop2
  14110.            MOVEM.L (A7)+,D2/D3
  14111.   HexEnd:  CLR.B   (A1)                     * Terminate string
  14112.            RTS                              * .. and return
  14113.  
  14114.   Digits:  DC.B    '0123456789ABCDEF'
  14115.  
  14116.   Even:    MOVE.L  4(A7),D0
  14117.            ADDQ.L  #1,D0
  14118.            AND.L   #1,D0
  14119.            RTS
  14120.  
  14121.  
  14122.            SECTION DemoData,DATA
  14123.            CNOP    0,2
  14124.  
  14125.   CapitalType:   DC.W    ProcTypeId       * Procedure
  14126.                  DC.W    0                * No return value
  14127.                  DC.L    0                * Always set to zero
  14128.                  DC.W    $0000            * No flags
  14129.                  DC.B    4                * Sec. stack (REF)
  14130.                  DC.B    4                * Address = 4 bytes
  14131.                  DC.W    1                * One parameter
  14132.                  DC.B    $80              * REF parameter
  14133.                  DC.B    0                * Always zero
  14134.                  DC.W    StringTypeId     * Parameter type
  14135.  
  14136.  
  14137.                                          248
  14138.  
  14139.  
  14140.  
  14141.  
  14142.  
  14143.   HexType:       DC.W    FuncTypeId       * Function
  14144.                  DC.W    StringTypeId     * Return value
  14145.                  DC.L    0
  14146.                  DC.W    $0001            * C string is returned
  14147.                  DC.B    0                * No sec. stack use
  14148.                  DC.B    4                * Int paramter = 4 bytes
  14149.                  DC.W    1                * One parameter
  14150.                  DC.B    $00              * Value parameter
  14151.                  DC.B    0
  14152.                  DC.W    UlongTypeId      * Parameter type
  14153.  
  14154.   EvenType:      DC.W    FuncTypeId       * Function
  14155.                  DC.W    ShortTypeId      * Return type
  14156.                  DC.L    0
  14157.                  DC.W    $0000            * No flags
  14158.                  DC.B    0                * No sec. stack use
  14159.                  DC.B    4                * Int parameter = 4 bytes
  14160.                  DC.W    1                * One parameter
  14161.                  DC.B    $00              * Value parameter
  14162.                  DC.B    0
  14163.                  DC.W    LongTypeId       * Parameter type
  14164.  
  14165.  
  14166.   NameTable:     DC.L    CapitalName
  14167.                  DC.L    CapitalType
  14168.                  DC.L    Capital
  14169.  
  14170.                  DC.L    HexName
  14171.                  DC.L    HexType
  14172.                  DC.L    Hex
  14173.  
  14174.                  DC.L    EvenName
  14175.                  DC.L    EvenType
  14176.                  DC.L    Even
  14177.  
  14178.   CapitalName:   DC.B    'Capital',0
  14179.   HexName:       DC.B    'Hex$',0
  14180.   EvenName:      DC.B    'Even',0
  14181.  
  14182.                  SECTION DemoBlock,BSS
  14183.                  CNOP    0,2
  14184.  
  14185.   ComalStruc:    DS.L    1
  14186.  
  14187.                  END
  14188.  
  14189.  
  14190.   This source has to be compiled and linked.  Public domain  assemblers and
  14191.   linkers will do the work.
  14192.  
  14193.  
  14194.                                          249
  14195.  
  14196.  
  14197.  
  14198.  
  14199.  
  14200.  
  14201.   3 Programming modules in C.
  14202.  
  14203.   It is  a very simple task to write modules in C (provided you know how to
  14204.   program in C).
  14205.  
  14206.   The interface part is written as (almost) normal Comal FUNC or PROC lines
  14207.   in a  separate text  file and then compiled by the compiler CompInterface
  14208.   (found in the ModuleDev directory on the Comal.Extras disk).
  14209.  
  14210.   The initialization routine (optional), the signal routine (optional) and all
  14211.   other routines are written as normal C procedures or functions.
  14212.  
  14213.   As an  example let's  make a  module containing these three functions and
  14214.   procedures:
  14215.  
  14216.     FUNC Even(i OF LONG) OF SHORT
  14217.     FUNC Hex$(i OF ULONG)
  14218.     PROC Capital(REF t$)
  14219.  
  14220.  
  14221.   3.1 The interface part.
  14222.  
  14223.   First let's make the interface part. The source text for the interface com-
  14224.   piler CompInterface is written in an editor. The source looks like:
  14225.  
  14226.     // Interface for Module Demo
  14227.  
  14228.       FUNC Even(i OF LONG) OF SHORT
  14229.       FUNC Hex$(i OF ULONG)
  14230.       PROC Capital(REF s$)
  14231.  
  14232.  
  14233.   Note that comments and empty lines may be used as in Comal.
  14234.  
  14235.   This source file is stored on disk as Demo.interface and then it is compiled
  14236.   by executing the following  shell (CLI)  command (provided Demo.interface
  14237.   and CompInterface are placed in the current directory)
  14238.  
  14239.       CompInterface Demo.interface
  14240.  
  14241.  
  14242.   The output  from CompInterface  is an assembler source text with the name
  14243.   Demo.interface.a. This is compiled with a normal assembler (for instance the
  14244.   SAS/C assembler)  by executing the command (the include file Comal.i must
  14245.   be in the current directory):
  14246.  
  14247.       lc:asm Demo.interface.a
  14248.  
  14249.  
  14250.  
  14251.                                          250
  14252.  
  14253.  
  14254.  
  14255.  
  14256.  
  14257.   The output from the assembler is an object file Demo.interface.o ready to
  14258.   be linked.
  14259.  
  14260.  
  14261.   3.2 The procedures and functions.
  14262.  
  14263.   The routines  in a  C programmed  module are  made as normal C procedures
  14264.   and functions. The names and the  types are  those used  in the interface
  14265.   source. You only have to know that strings (marked with a dollar sign ($)
  14266.   in the interface source) must be changed to 'char *' and that  the dollar
  14267.   sign are omitted from the name (see the function Hex$ in the example).
  14268.  
  14269.   The C source for the module we are making as an example looks like this:
  14270.  
  14271.   /* Module Demo */
  14272.  
  14273.   #include <exec/types.h>
  14274.   #include <string.h>
  14275.   #include <ctype.h>
  14276.   #include "Comal.h"
  14277.   #include "Comal_protos.h"
  14278.  
  14279.   short Even(LONG i)
  14280.   {
  14281.     return( (i+1) & 0x01 );
  14282.   }
  14283.  
  14284.   char *Hex(ULONG i)
  14285.   {
  14286.     char *String;
  14287.     
  14288.     /* Place return string in workspace    */
  14289.     String = ComalStruc->CurrWorkBottom;
  14290.     if ( ComalStruc->CurrWorkBottom+14 >= ComalStruc->CurrWorkTop )
  14291.       ErrorText("Out of memory");
  14292.     ComalStruc->CurrWorkBottom += 14;
  14293.     String[0] = '$';
  14294.     (void)stcl_h(String+1,i);
  14295.     return( String );
  14296.   }
  14297.  
  14298.   void Capital(char *Str)
  14299.   {
  14300.     while ( *Str )
  14301.     {
  14302.       if ( islower(*Str) )
  14303.         *Str = *Str - ('a'-'A');
  14304.       Str++;
  14305.     }
  14306.   }
  14307.  
  14308.                                          251
  14309.  
  14310.  
  14311.  
  14312.  
  14313.  
  14314.  
  14315.  
  14316.   This program  is stored  on disk  under the name Demo.c and then compiled
  14317.   by executing the command (SAS/C compiler)
  14318.  
  14319.     lc:LC -b0 -fi -oDemo.o Demo
  14320.  
  14321.  
  14322.   The output from the compiler is an object file ready to be linked.
  14323.  
  14324.  
  14325.   3.3 Linking the object files.
  14326.  
  14327.   The object files made by the assembler and the C compiler has to be linked
  14328.   together. This is done by the following command (again the SAS/C linker is
  14329.   used):
  14330.  
  14331.     lc:blink Demo.interface.o Demo.o TO Comal:Modules/Demo
  14332.                     LIBRARY Comal.lib lib:lcnb.lib lib:Amiga.lib
  14333.  
  14334.   (type in as one line).
  14335.  
  14336.   The output from the linker is a module Demo placed in the  directory Com-
  14337.   al:Mudules and the module can be used by placing the line
  14338.  
  14339.     USE Demo
  14340.  
  14341.   in a Comal program.
  14342.  
  14343.  
  14344.   3.4 An initialization routine.
  14345.  
  14346.   The interface compiler CompInterface makes the basic initialization code for
  14347.   you. If you need to do more initialization you have to place the following
  14348.   function in your code (NOTE! The name must be ModuleInit):
  14349.  
  14350.     short ModuleInit(void)
  14351.     {
  14352.  
  14353.         :
  14354.  
  14355.     }
  14356.  
  14357.  
  14358.   The function returns zero if the initialization succeded. Otherwise an error
  14359.   code greater than 5 is returned.
  14360.  
  14361.  
  14362.   Example: Here is a simple initialization routine:
  14363.  
  14364.  
  14365.                                          252
  14366.  
  14367.  
  14368.  
  14369.  
  14370.  
  14371.     short ModuleInit(void)
  14372.     {
  14373.       if ( !(DOSBase = OpenLibrary("dos.library",0)) )
  14374.         return(100);
  14375.       else
  14376.         return(0);
  14377.     }
  14378.  
  14379.  
  14380.   3.5 A signal routine.
  14381.  
  14382.   If you need to receive signals from the  Comal system  a signal procedure
  14383.   has to placed in your code (NOTE! The name must be signal):
  14384.  
  14385.     void signal(short s)
  14386.     {
  14387.       :
  14388.     }
  14389.  
  14390.   Example: A signal routine is very often used to close libbraries.
  14391.  
  14392.     void signal(short s)
  14393.     {
  14394.       switch(s)
  14395.       {
  14396.         case SIG_CLOSE:
  14397.         case SIG_DISCARD: 
  14398.           if( DOSBase )
  14399.           {
  14400.             CloseLibrary(DOSBase);
  14401.             DOSBase = NULL;
  14402.           }
  14403.         case SIG_CLEAR:
  14404.         case SIG_RUN:
  14405.         case SIG_STOP:
  14406.         case SIG_END:
  14407.           break;
  14408.       }
  14409.     }
  14410.  
  14411.  
  14412.   3.4 Using the script file MakeMod.
  14413.  
  14414.   All the command used to make a module is placed in a script file MakeMod
  14415.   (found in the ModuleDev directory on the Comal.Extras disk). Provided that
  14416.   both source files (Demo.interface and Demo.c) are placed in the same direc-
  14417.   tory as  MakeMod and  Comal.h, Comal_protos.h, Comal.i, and Comal.lib the
  14418.   module can be made simply by executing the command:
  14419.  
  14420.     MakeMod Demo
  14421.  
  14422.                                          253
  14423.  
  14424.  
  14425.  
  14426.  
  14427.  
  14428.  
  14429.  
  14430.   3.5 The interface compiler CompInterface.
  14431.  
  14432.   The interface compiler CompInterface takes as input a text file containing
  14433.   normal Comal procedure and function heads. The command template is:
  14434.  
  14435.     CompInterface [options] filename
  14436.  
  14437.  
  14438.   Options are specified as a hyphen followed by a single letter. Current op-
  14439.   tions are:
  14440.  
  14441.     -o  This option is followed by a  directory path.  The output  from the
  14442.         compiler is placed in that directory. Default output path is the cur-
  14443.         rent directory.
  14444.  
  14445.     -i  If this option is used, the interface source is added as the modules
  14446.         informationtext (the  text you  get when selecting the Show Modules
  14447.         menu item in the Program menu).
  14448.  
  14449.     -p  If this option is used, all functions (except string functions) can be
  14450.         used as procedures, too.
  14451.  
  14452.  
  14453.   The output  from CompInterface is an assembler source text that has to be
  14454.   compiled by a normal assembler.
  14455.  
  14456.  
  14457.   4 Calling internal Comal routines from modules.
  14458.  
  14459.   A number of routines in the  Comal system  may be  called from  a module.
  14460.   These routines are:
  14461.  
  14462.  
  14463.     void ErrorNumber(short ErrorCode);
  14464.             -6                D2
  14465.  
  14466.       Stop execution with error message. No return from the routine.
  14467.  
  14468.  
  14469.     void ErrorText(char *ErrorText);
  14470.             -12            D0
  14471.  
  14472.       Stop execution with error text. No return from the routine.
  14473.  
  14474.  
  14475.  
  14476.  
  14477.  
  14478.  
  14479.                                          254
  14480.  
  14481.  
  14482.  
  14483.  
  14484.  
  14485.     void ExecBreak(void);
  14486.             -18
  14487.  
  14488.       Call this routine if the break flag is set in the Comal structure (see
  14489.       the include files). No return from the routine unless the execution are
  14490.       continued or the break is disabled (SET ESC statement).
  14491.  
  14492.  
  14493.     struct Window *LockComalWindow(void);
  14494.             -24
  14495.  
  14496.       Get a  shared lock  for the standard IO window. The routine will open
  14497.       the standard IO window (if not already opened) and return a pointer to
  14498.       the window structure.
  14499.  
  14500.  
  14501.     void UnlockComalWindow(void);
  14502.             -30
  14503.  
  14504.       Release the lock for the standard IO window.
  14505.  
  14506.  
  14507.     void AddComalDevice(struct IoDevice *Device);
  14508.             -36                       A0
  14509.  
  14510.       Add an IO device. The parameter is a pointer to an initialized IO devi-
  14511.       ce structure. This structure will be put into the start of the list of
  14512.       standard IO devices (like "ds:").
  14513.  
  14514.     void RemComalDevice(struct IoDevice *Device);
  14515.             -42                       A0
  14516.  
  14517.       Remove an  IO device  from the list of IO devices. The parameter is a
  14518.       pointer to the IO device to be removed.
  14519.  
  14520.  
  14521.     unsigned long ComalWait(unsigned long SignalMask);
  14522.             -48                             D0
  14523.  
  14524.       Wait for the signals in the signalmask and all the Comal signals. The
  14525.       routine ORs  all the  Comal signals  to SignalMask and then calls the
  14526.       Exec routine Wait.
  14527.  
  14528.  
  14529.     void AddExcept(struct ExceptStruc *Except);
  14530.             -54                         A0
  14531.  
  14532.       Add an exception routine to the list of exception routines in the Comal
  14533.       system. The parameter is an initialized structure of the form:
  14534.  
  14535.  
  14536.                                          255
  14537.  
  14538.  
  14539.  
  14540.  
  14541.  
  14542.         struct ExceptStruc
  14543.         {
  14544.           struct ExceptStruc *Next;
  14545.           ULONG SignalMask;
  14546.           void  (*ExceptRoutine)(ULONG,struct ExceptStruc *);
  14547.           APTR  IdField;
  14548.         };
  14549.  
  14550.       The field  SignalMask is a mask containing the exception signals. Ex-
  14551.       ceptRoutine is the address of your exception routine. This routine is
  14552.       called with a mask containing the signals that caused the exception and
  14553.       a pointer to the exception structure. The field IdField is for your own
  14554.       purpose.
  14555.  
  14556.  
  14557.     void RemExcept(struct ExceptStruc *Except);
  14558.             -60                         A0
  14559.  
  14560.       Remove an exception routine from the list of exception routines in the
  14561.       Comal system. The parameter is a pointer to the exception structure to
  14562.       be removed from the exception list.
  14563.  
  14564.  
  14565.     void AddSignal(unsigned long SignalMask);
  14566.             -66                     D0
  14567.  
  14568.       Add a signal to the Comal signals.
  14569.  
  14570.  
  14571.     void RemSignal(unsigned long SignalMask);
  14572.             -72                     D0
  14573.  
  14574.       Remove a signal from the Comal signals.
  14575.  
  14576.  
  14577.     short GetAccept(char *Str, char *Accept, char *Cancel);
  14578.             -78           A0          A1            A2
  14579.  
  14580.       Set up  a requester. The parameter Str is the text written in the re-
  14581.       quester. This string may contain the C formatting character '\r'. The
  14582.       parameters Accept  and Cancel are the text filled in the positive and
  14583.       negative gadgets respectively.
  14584.  
  14585.       The routine returns TRUE if the positive gadget was pressed. Otherwise
  14586.       it returns FALSE.
  14587.  
  14588.  
  14589.   The routines are organized as an Amiga library with jump vectors at nega-
  14590.   tive offsets (the numbers shown under the names) from the Comal structure.
  14591.   From an  assembler program  it must  be called  with the  address of this
  14592.  
  14593.                                          256
  14594.  
  14595.  
  14596.  
  14597.  
  14598.  
  14599.   structure in register A6. Here is a typical calling sequence:
  14600.  
  14601.           MOVE.L  ComalStruc,A6
  14602.           JSR     -LVORemSignal(A6)
  14603.  
  14604.   All the routines uses the registers D0-D1/A0-A1. All other registers are un-
  14605.   changed.
  14606.  
  14607.  
  14608.   5 Calling comal programmed routines from a module.
  14609.  
  14610.   A Comal programmed procedure or function is called as a C procedure, i.e.
  14611.   the parameters are transfered on the stack and a return value is returned
  14612.   in register D0 (D0 and D1 if float).
  14613.  
  14614.   Example: We  will make  a module  containing an  integral function of the
  14615.     form:
  14616.  
  14617.       FUNC integral(f OF FltFnc, a, b)
  14618.  
  14619.       TYPE FltFnc=FUNC(FLOAT) OF FLOAT
  14620.  
  14621.  
  14622.     The interface looks like:
  14623.  
  14624.  
  14625.     // Interface for integral module
  14626.  
  14627.       FUNC integral(f OF FUNC OF FLOAT,a OF FLOAT,b OF FLOAT) OF FLOAT
  14628.  
  14629.  
  14630.     and the code like this:
  14631.  
  14632.  
  14633.     /* Integral module    version 92.07.29  */
  14634.  
  14635.     #include <math.h>
  14636.     #include "Comal.h"
  14637.     #include "Comal_protos.h"
  14638.  
  14639.     double integral(double (*f)(),double a, double b, struct ProcType *Inf)
  14640.     {
  14641.       double xi, s, dx;
  14642.       int n;
  14643.     
  14644.       if ( (Inf->NumPar != 1) ||
  14645.             (*((ULONG *)(Inf->Param)) != (0x0000FFFF & FLOAT_ID)) )
  14646.         ErrorText("Illegal function parameter");
  14647.  
  14648.       n = 16;
  14649.  
  14650.                                          257
  14651.  
  14652.  
  14653.  
  14654.  
  14655.  
  14656.       dx = (b-a)/n;
  14657.       xi = a;
  14658.       s = (f(a)-f(b))*dx/6.0;
  14659.       while ( (n--) > 0 )
  14660.       {
  14661.         xi = xi+dx;
  14662.         s = s+(f(xi)+2*f(xi-dx/2))*dx/3;
  14663.       }
  14664.       return(s);
  14665.     }
  14666.  
  14667.  
  14668.   One thing has to be noted. At the call to a Comal  programmed routine the
  14669.   register A4  must point to the data used by the Comal system. At the call
  14670.   of your own routine the register A4 has the correct  value and  if you do
  14671.   not touch this register, there is no problem.
  14672.  
  14673.   But what  about C compiled code? How can you be sure that the register A4
  14674.   is not used by the code made by your compiler?
  14675.  
  14676.   As a general answer to that question we have to  say, that  you cannot be
  14677.   sure! Fortunately it seems as if SAS/C (version 5.10) do not use the regis-
  14678.   ter if it is compiled in "non base relative" mode (use the nb-libraries) and
  14679.   if you do not use the math library (the one containing the functions sin,
  14680.   cos, tan, ...). Replacement for most of the functions are placed in Comal.lib.
  14681.  
  14682.  
  14683.   6 Making a library interface.
  14684.  
  14685.   From time to time new libraries for the Amiga appears (a lot  of them are
  14686.   public domain).  It is a very simple task to make an interface for such a
  14687.   library.
  14688.  
  14689.   As an example we will make an interface  for the  ReqTools.Library (found
  14690.   on Fish disk #575).
  14691.  
  14692.   First we  have to make an interface source file. This is best done if you
  14693.   have a C proto include file for the functions in the library. Such a file is
  14694.   supplied with the ReqTools.Library. A small part of this file looks like:
  14695.  
  14696.     APTR rtAllocRequestA(ULONG, struct TagItem *);
  14697.     void rtFreeRequest(APTR);
  14698.     void rtFreeReqBuffer(APTR);
  14699.     LONG rtChangeReqAttrA(APTR, struct TagItem *);
  14700.             :
  14701.  
  14702.  
  14703.   The proto file is changed to an interface file in this way:
  14704.  
  14705.  
  14706.  
  14707.                                          258
  14708.  
  14709.  
  14710.  
  14711.  
  14712.  
  14713.   // Interface for reqtools.library
  14714.  
  14715.     FUNC rtAllocRequestA type OF ULONG, TagItem OF ULONG) OF ULONG
  14716.     PROC rtFreeRequest(req OF ULONG)
  14717.     PROC rtFreeReqBuffer(req OF ULONG)
  14718.     FUNC rtChangeReqAttrA(req OF ULONG, TagItem OF ULONG) OF LONG
  14719.             :
  14720.  
  14721.  
  14722.   Note that pointers are changed to ULONG.
  14723.  
  14724.   Now we  are going  to make the code. This contains only an initialization
  14725.   and a signal routine:
  14726.  
  14727.  
  14728.   /*********************************************************************/
  14729.   /*                                                                   */
  14730.   /*    ReqTools library - version 92.05.11                            */
  14731.   /*                                                                   */
  14732.   /*********************************************************************/
  14733.  
  14734.   #include <exec/types.h>
  14735.   #include <proto/exec.h>
  14736.   #include <pragmas/exec.h>
  14737.   #include "Comal.h"
  14738.   #include "Comal_protos.h"
  14739.  
  14740.   struct Library *ReqToolsBase = NULL;
  14741.  
  14742.   short ModuleInit(void)
  14743.   {
  14744.     if ( !(ReqToolsBase = OpenLibrary("reqtools.library",37)) )
  14745.       return(0);
  14746.     else
  14747.       return(150);
  14748.   }
  14749.  
  14750.   void signal(short s)             /* Signal routine */
  14751.   {
  14752.     switch(s)
  14753.     {
  14754.       case SIG_CLOSE:
  14755.       case SIG_DISCARD: 
  14756.         if( ReqToolsBase )
  14757.           CloseLibrary(ReqToolsBase);
  14758.     }
  14759.   }
  14760.  
  14761.  
  14762.  
  14763.  
  14764.                                          259
  14765.  
  14766.  
  14767.  
  14768.  
  14769.  
  14770.   The files are compiled as usual. To link it you have to specify the ReqTools
  14771.   linker library:
  14772.  
  14773.     blink ReqToolsLibrary.Interface.o ReqToolsLibrary.o
  14774.       TO Comal:Modules/ReqToolsLibrary
  14775.       LIBRARY Comal.lib reqtoolsnb.lib Lib:lcnb.lib Lib:Amiga.lib
  14776.  
  14777.   (NOTE! one line only).
  14778.  
  14779.  
  14780.  
  14781.  
  14782.  
  14783.  
  14784.  
  14785.  
  14786.  
  14787.  
  14788.  
  14789.  
  14790.  
  14791.  
  14792.  
  14793.  
  14794.  
  14795.  
  14796.  
  14797.  
  14798.  
  14799.  
  14800.  
  14801.  
  14802.  
  14803.  
  14804.  
  14805.  
  14806.  
  14807.  
  14808.  
  14809.  
  14810.  
  14811.  
  14812.  
  14813.  
  14814.  
  14815.  
  14816.  
  14817.  
  14818.  
  14819.  
  14820.  
  14821.                                          260
  14822.  
  14823.  
  14824.  
  14825.  
  14826.  
  14827.   X. APPENDIX
  14828.  
  14829.  
  14830.   A. Customizing the Comal text.
  14831.  
  14832.   All texts used in the Comal system are stored in two files Comal.texts and
  14833.   Comal.interpreter.texts found in the Prefs/Texts drawer.  These files are
  14834.   simple ASCII files and it is a simple matter to edit these files.
  14835.  
  14836.   The format  of the  files is  shown in the following fraction of the file
  14837.   Comal.texts:
  14838.  
  14839.   /* Other window title texts */
  14840.   #052  "Comal - project"
  14841.   #053  "Command - project"
  14842.   #054  "Error - project"
  14843.   #055  "Comal module library"
  14844.   #056  "Comal module information text"
  14845.   #057  "Comal watch window"
  14846.  
  14847.   /* About window texts */
  14848.   #058  "About Comal ..."
  14849.   #059  "Comal version 3.01"
  14850.   #060  "Total memory available:"
  14851.   #061  " bytes of memory for program text"
  14852.   #062  " bytes of workspace memory for running program"
  14853.   #063  "Comal was designed and developed by:"
  14854.   #064  "Svend Daugaard Pedersen"
  14855.  
  14856.  
  14857.   /* Menu texts  */
  14858.   #065  "Project"                         /* Menu name    */
  14859.   #066  "New"                             /* Item name    */
  14860.   #067  "N"                               /* Short cut    */
  14861.   #068  "Open..."                         /* Item name    */
  14862.   #069  "O"                               /* Short cut    */
  14863.   #070  "Save"                            /* etc.         */
  14864.   #071  "S"
  14865.   #072  "Save As..."
  14866.   #073  "A"
  14867.   #074  "Print"
  14868.   #075  "P"
  14869.   #076  "Open Command Window"
  14870.   #077  "K"
  14871.   #078  "About..."
  14872.   #079  ""
  14873.   #080  "Clear Program Buffer"
  14874.   #081  ""
  14875.   #082  "Quit Project"
  14876.   #083  "Q"
  14877.  
  14878.                                          261
  14879.  
  14880.  
  14881.  
  14882.  
  14883.  
  14884.  
  14885.   Each text is placed in one line and this line starts with the number of the
  14886.   text. The text itself is placed in double quotes and consists of ASCII cha-
  14887.   racters or the C style codes '\n' (new line), '\"' (double quote) or '\\' (for
  14888.   the character '\').
  14889.  
  14890.   All texts  must be  defined and  the numbers must be placed in increasing
  14891.   order. The first line has number zero. Empty lines and the use of C style
  14892.   comments are allowed.
  14893.  
  14894.   Note that  each menu item and subitem text consist of two texts - one for
  14895.   the text itself and one for the menu short cut. If the short cut text is the
  14896.   empty text (the text ""), no short cut will be available.
  14897.  
  14898.   Having made  a new set of text files they must be stored in the directory
  14899.   Prefs/Texts using file names of the forms:
  14900.  
  14901.     Comal.<text_id>
  14902.  
  14903.   and
  14904.  
  14905.     Comal.Interpreter.<text_id>
  14906.  
  14907.  
  14908.   Normally the <text_id> is the name of a language but it could be anything
  14909.   (but the same for both files!).
  14910.  
  14911.  
  14912.   B. The format of the AREXX macro file.
  14913.  
  14914.   At start Comal searches for a file Comal.macro containing macro definitions.
  14915.   The format of a macro file is shown in the following example:
  14916.  
  14917.   #0 SaveBlock
  14918.   #1 SaveModule
  14919.   #2 SaveModule3
  14920.   #3 StartProgram
  14921.   #4 'StartProgram Comal:Programs/Integral'
  14922.  
  14923.  
  14924.   Each macro line starts with a number sign (#), one digit (0,1,2,..,9), a blank
  14925.   (a space) and the macro string itself. If a line does not start with # it is
  14926.   treated as a comment.
  14927.  
  14928.   The line starting with #0 is attached the function key F1, the line starting
  14929.   with #1 is attached the function key F2 etc.
  14930.  
  14931.  
  14932.  
  14933.  
  14934.  
  14935.                                          262
  14936.  
  14937.  
  14938.  
  14939.  
  14940.  
  14941.   C. Customizing Comal.lib.
  14942.  
  14943.   The link library file Comal.lib found in the directory ModuleDev contains
  14944.   interfaceroutines for the Comal routines as well as initialization and termi-
  14945.   nation code for a C programmed module.
  14946.  
  14947.   The initialization and termination code is compiler dependent and the code
  14948.   found in Comal.lib is for use with the  SAS/C compiler.  In the directory
  14949.   ModuleDev you will also find a file Comal0.lib which is a library file with-
  14950.   out the initialization and termination code. This one can be used to make a
  14951.   library file for other C compilers.
  14952.  
  14953.   As part of the initialization a routine by name C_Init is called and when
  14954.   the module is removed a routine C_Term is called. These routines should do
  14955.   the initialialization and termination necessary for your C compiled code. To
  14956.   make it you should look at the source for the c.o startup code.
  14957.  
  14958.   Here is the code used for SAS/C:
  14959.  
  14960.  
  14961.   ; Module startup for SAS C v.5.xx  -  version 92.07.29
  14962.   ;
  14963.  
  14964.                  include  Comal.i
  14965.  
  14966.                  XDEF     __base
  14967.                  XDEF     _XCEXIT
  14968.                  XDEF     __xcovf
  14969.                  XDEF     _SysBase
  14970.                  XDEF     C_Init
  14971.                  XDEF     C_Term
  14972.  
  14973.                  XREF     _LinkerDB
  14974.                  XREF     ___fpinit
  14975.                  XREF     ___fpterm
  14976.                  XREF     _ComalStruc
  14977.  
  14978.   AbsExecBase    EQU       $4
  14979.  
  14980.                  SECTION  InterfaceCode,CODE
  14981.                  CNOP     0,2
  14982.  
  14983.   ; Initialization routine
  14984.   ;
  14985.   C_Init:        MOVE.L  _ComalStruc,A0       ; Get Comal structure
  14986.                  MOVE.L  CS_MinStack(A0),D0   ; Get stack bottom
  14987.                  ADD.L   #$200,D0             ; Calculate "safe" bound
  14988.                  MOVE.L  D0,__base            ; .. and store
  14989.                  MOVE.L  AbsExecBase,_SysBase ; Set Exec base
  14990.  
  14991.  
  14992.                                          263
  14993.  
  14994.  
  14995.  
  14996.  
  14997.  
  14998.                  MOVE.L  A4,-(A7)             ; Initialize floating point
  14999.                  LEA     _LinkerDB,A4
  15000.                  JSR     ___fpinit
  15001.                  MOVE.L  (A7)+,A4
  15002.  
  15003.                  CLR.W   D0                   ; Set status
  15004.                  RTS                          ; .. and return
  15005.  
  15006.   ; Termination routine
  15007.   ;
  15008.   C_Term:        MOVE.L  A4,-(A7)
  15009.                  LEA     _LinkerDB,A4
  15010.                  JSR      ___fpterm           ; Terminate floating point
  15011.                  MOVE.L  (A7)+,A4
  15012.                  RTS
  15013.                  
  15014.  
  15015.   ; Report stack overflow (only used if stack check is turned on)
  15016.   ;
  15017.   __xcovf:       MOVEQ     #5,D2
  15018.   _XCEXIT:       MOVE.L    _ComalStruc,A0    ; Get Comal library base
  15019.                  JSR       -6(A0)            ; .. and return
  15020.  
  15021.                  SECTION   InterfaceBlock,BSS
  15022.                  CNOP      0,2
  15023.  
  15024.   _SysBase:      DS.L      1                 ; Exec library base
  15025.   __base:        DS.L      1                 ; "Safe" low bound of stack
  15026.  
  15027.                  END
  15028.  
  15029.  
  15030.  
  15031.  
  15032.  
  15033.  
  15034.  
  15035.  
  15036.  
  15037.  
  15038.  
  15039.  
  15040.  
  15041.  
  15042.  
  15043.  
  15044.  
  15045.  
  15046.  
  15047.  
  15048.  
  15049.                                          264
  15050.  
  15051.